2011-06-22 3 views
1

J'ai un projet web avec internationalisation. C'est assez similaire à http://www.springbyexample.org/examples/basic-webapp-internationalization-jsp-example.html. Il existe des liens permettant de changer les paramètres régionaux dans le décorateur. Ils ajoutent lang param à l'URL actuelle:Internationalisation de printemps: changement de paramètres régionaux

<a href="?lang=en">En</a> | <a href="?lang=ru">Ru</a> </span></td> 

À la première fois, l'internationalisation a bien fonctionné. Mais ensuite nous avons trouvé un problème avec certaines formes. Forme:

<form:form action="${pageContext.request.contextPath}/branch/${branchId}/topic.html" modelAttribute="topicDto" method="POST" 
onsubmit="this.getAttribute('submitted')"> <!--Block multiple form submissions--> 
<table border="2" width="100%"> 
    <tr> 
     <td width="30%"> 
      <form:label path="topicName"><spring:message code="label.topic"/></form:label> 
      <form:input path="topicName"/> 
      <form:errors path="topicName"/> 
     </td> 
    </tr> 
    <tr> 
     <td height="200"> 
      <form:label path="bodyText"><spring:message code="label.text"/></form:label> 
      <form:textarea path="bodyText"/> 
      <form:errors path="bodyText"/> 
     </td> 
    </tr> 
</table> 
<input type="submit" value="<spring:message code="label.addtopic"/>"/> 

contrôleur

:

/** 
* @see Topic 
*/ 
@Controller 
public final class TopicController { 
/** 
* Method handles newTopic.html GET request and display page for creation new topic 
* 
* @param branchId {@link org.jtalks.jcommune.model.entity.Branch} id 
* @return {@code ModelAndView} object with "newTopic" view, new {@link TopicDto} and branch id 
*/ 
@RequestMapping(value = "/branch/{branchId}/topic/create", method = RequestMethod.GET) 
public ModelAndView createPage(@PathVariable("branchId") Long branchId) { 
    return new ModelAndView("newTopic") 
      .addObject("topicDto", new TopicDto()) 
      .addObject("branchId", branchId); 
} 

/** 
* This method handles POST requests, it will be always activated when the user pressing "Submit topic" 
* 
* @param topicDto the object that provides communication between spring form and controller 
* @param result {@link BindingResult} object for spring validation 
* @param branchId hold the current branchId 
* @return {@code ModelAndView} object which will be redirect to forum.html 
* @throws org.jtalks.jcommune.service.exceptions.NotFoundException 
*   when branch not found 
*/ 
@RequestMapping(value = "/branch/{branchId}/topic", method = RequestMethod.POST) 
public ModelAndView create(@Valid @ModelAttribute TopicDto topicDto, 
          BindingResult result, 
          @PathVariable("branchId") Long branchId) throws NotFoundException { 
    if (result.hasErrors()) { 
     return new ModelAndView("newTopic").addObject("branchId", branchId); 
    } else { 
     Topic createdTopic = topicService.createTopic(topicDto.getTopicName(), topicDto.getBodyText(), 
       branchId); 
     return new ModelAndView("redirect:/branch/" + branchId + "/topic/" 
       + createdTopic.getId() + ".html"); 
    } 
} 

}

Si l'utilisateur afficher le formulaire avec des champs non valides, il verra des messages de validation avant que les champs. S'il changer la langue de la page à ce moment il verra l'erreur:

HTTP Status 405 - Request method 'GET' not supported 
type Status report 
message Request method 'GET' not supported 
description The specified HTTP method is not allowed for the requested resource (Request method  'GET' not supported). 
Apache Tomcat/7.0.11 

vous pouvez vérifier le problème vous-même à notre serveur de développement http://deploy.jtalks.org/jcommune/index.html par exemple à la page d'inscription http://deploy.jtalks.org/jcommune/registration.html laisser le formulaire vierge et le soumettre. Vous verrez des messages de validation. que changer la langue et soumettre le formulaire une fois de plus pour voir l'erreur spécifiée.

Vous pouvez trouver toutes nos sources ici http://fisheye.jtalks.org/

Répondre

0

I a fixé le porblem en changeant la correspondance entre

@RequestMapping(value = "/branch/{branchId}/topic", method = RequestMethod.POST) 

à

@RequestMapping(value = "/branch/{branchId}/topic", method = {RequestMethod.POST, RequestMethod.GET}) 

et l'erreur a disparu.

1

Vous le paramètre lang AJOUT DE à quelque URL que vous a apporté à la page. Donc, si vous arrivez au formulaire via /registration.html, les liens En et Ru mènent également à/registration.html. Vraisemblablement, ce contrôleur supporte GET, donc quand vous cliquez sur un lien et générez une requête GET, tout fonctionne. Une fois le formulaire POSTé, les liens En et Ru mènent à /user.html car, bon, c'est comme cela que vous avez programmé la page. Cliquez sur ces liens, et vous générez une requête GET à /user.html. Vraisemblablement cela échoue parce que le contrôleur pour/user.html soutient POST mais pas GET.

FYI vous pouvez voir exactement ce qui se passe côté client et côté serveur. Dans les deux cas, utilisez n'importe quel nombre d'outils pour regarder le trafic HTTP aller et venir.

Il est probable que vous utilisiez Spring de telle sorte que la commutation des langues s'effectue côté serveur, vous devez donc RETIRER la page actuelle. Pour corriger votre formulaire d'inscription en particulier, le plus simple sera de jeter les données que l'utilisateur a déjà saisies, et de simplement passer le lien pour pointer vers/registration.html même après la validation du formulaire échoue. (En d'autres termes, le lien ne doit PAS être généré en fonction de l'URL qui vous a amené à la page.) Les chances sont que l'utilisateur ne changera pas les langues au milieu de toute façon. Toutefois, si vous devez conserver les données de formulaire, une approche différente est requise.

+0

Merci pour l'explication. Mais que puis-je faire pour éviter cette erreur? Je peux rediriger l'utilisateur à la page principale sur le langage swithcing. Mais ce n'est pas convivial. Peut être que je peux confirmer que GET param quelque part avant le contrôleur? – NullPointer

+0

Je peux aussi définir le cookie javascript spécifique à spirng au lieu de passer GET-param. Cela fonctionne bien, mais je pense que ce n'est pas la meilleure solution. – NullPointer

0

Je pense que vous devez utiliser le pattern POST/REDIRECT/GET.

http://en.wikipedia.org/wiki/Post/Redirect/Get

Par exemple:

@Controller 
public final class TopicController { 

@RequestMapping(value = "/branch/{branchId}/topic/create", method = RequestMethod.GET) 
public ModelAndView createPage(@PathVariable("branchId") Long branchId) { 
    return new ModelAndView("newTopic") 
      .addObject("topicDto", new TopicDto()) 
      .addObject("branchId", branchId); 
} 

@RequestMapping(value = "/branch/{branchId}/topic", method = RequestMethod.POST) 
public ModelAndView create(@Valid @ModelAttribute TopicDto topicDto, 
          BindingResult result, 
          @PathVariable("branchId") Long branchId) throws NotFoundException { 
    if (result.hasErrors()) { 
     return new ModelAndView("newTopic").addObject("branchId", branchId); 
    } else { 

     /*Here you must create your topic, and add to DB, then redirect..*/ 

     return new ModelAndView("redirect:/TO_THE_VIEW_PAGE"); 
    } 
} 

@RequestMapping(value = "/TO_THE_VIEW_PAGE", method = RequestMethod.GET) 
public ModelAndView view(/*need parameters*/) { 

    /*...There you must get your topic from DB, and go to view page..*/ 

    return new ModelAndView("/PATH_TO_THE_VIEW_PAGE"); 
} 

Si vous devez transmettre des données (objet) à la méthode (view) qui a appelé après redirect, vous pouvez utiliser RedirectAttributes classe. http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/servlet/mvc/support/RedirectAttributes.html

Par exemple:

@RequestMapping(value = "/branch/{branchId}/topic", method = RequestMethod.POST) 
public ModelAndView create(@Valid @ModelAttribute TopicDto topicDto, 
          BindingResult result, 
          @PathVariable("branchId") Long branchId, 
          RedirectAttributes redirectAttributes) throws NotFoundException { 

     redirectAttributes.addFlashAttribute("topic", topicDto); 
     redirectAttributes.addFlashAttribute("branchId", branchId); 

     return new ModelAndView("redirect:/TO_THE_VIEW_PAGE"); 
    } 
} 

ensuite obtenir ces attributs dans la méthode view.

Questions connexes