簡體   English   中英

春季國際化:地區變更問題

[英]Spring internationalization: locale change problem

我有一個國際化的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生成鏈接。)用戶有可能無論如何都不會在中間切換語言。 但是,如果必須保留表單數據,則需要使用其他方法。

我想您必須使用POST / REDIRECT / GET模式。

http://zh.wikipedia.org/wiki/郵寄/重定向/獲取

例如:

@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 )方法,則可以使用RedirectAttributes類。 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方法中獲取那些屬性。

我通過更改映射來修復了問題

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

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

錯誤消失了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM