春季国际化:语言环境更改问题

| 我有一个国际化的Web项目。它与http://www.springbyexample.org/examples/basic-webapp-internationalization-jsp-example.html非常相似。 在装饰器中有用于切换语言环境的链接。它们将lang参数添加到当前网址:
<a href=\"?lang=en\">En</a> | <a href=\"?lang=ru\">Ru</a> </span></td>
最初,国际化运作良好。但是后来我们发现某些形式存在问题。 形成:
<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\"/>\"/>
控制器:
/**
 * @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\");
    }
}
} 如果用户使用无效字段发布表单,它将在字段之前看到验证消息。如果他此时切换页面语言,将看到错误:
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
您可以在我们的开发服务器上自行检查问题 http://deploy.jtalks.org/jcommune/index.html 例如在注册页面 http://deploy.jtalks.org/jcommune/registration.html 将表格留空并提交。您将看到验证消息。而不是更改语言并再次提交表单以查看指定的错误。 您可以在这里找到我们所有的资源http://fisheye.jtalks.org/     
已邀请:
        您会将lang参数附加到将您带到该页面的任何URL。因此,如果您通过/registration.html进入表单,则En和Ru链接也将指向/registration.html。大概该控制器支持GET,因此,当您单击链接并生成GET请求时,一切正常。 发布表单后,“ En”和“ Ru”链接将指向/user.html,因为那样就可以对页面进行编程了。单击这些链接,然后生成对/user.html的GET请求。大概这失败了,因为/user.html的控制器支持POST,但不支持GET。 仅供参考,您可以确切地看到客户端和服务器端正在发生什么。在这两种情况下,都可以使用多种工具来观察HTTP流量的来回变化。 您使用Spring的方式可能是在服务器端进行语言切换,因此您需要再次获取实际页面。特别是要修正您的注册表单,最简单的方法是扔掉用户已经输入的数据,即使表单验证失败后,也只需将链接切换为指向/registration.html即可。 (换句话说,不应基于将您带到页面的任何URL生成链接。)用户有可能无论如何都不会在中间切换语言。但是,如果必须保留表单数据,则需要使用其他方法。     
        我通过更改映射来修复了问题
@RequestMapping(value = \"/branch/{branchId}/topic\", method = RequestMethod.POST)
@RequestMapping(value = \"/branch/{branchId}/topic\", method = {RequestMethod.POST, RequestMethod.GET})
错误消失了。     
        我想您必须使用POST / REDIRECT / GET模式。 http://en.wikipedia.org/wiki/Post/Redirect/Get 例如:
@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\");
}
如果需要将数据(对象)传递给重定向后调用的(
view
)方法,则可以使用use8ѭ类。 http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/servlet/mvc/support/RedirectAttributes.html 例如:
@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\");
    }
}
然后使用
view
方法获得这些属性。     

要回复问题请先登录注册