Весенняя интернационализация: проблема смены локали - PullRequest
1 голос
/ 22 июня 2011

У меня есть веб-проект с интернационализацией. Это очень похоже на http://www.springbyexample.org/examples/basic-webapp-internationalization-jsp-example.html. В декораторе есть ссылки для переключения локалей. Они добавляют параметр lang к текущему URL:

<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/

Ответы [ 3 ]

1 голос
/ 22 июня 2011

Вы добавляете параметр lang к любому URL, который привел вас на страницу. Таким образом, если вы перейдете к форме через /registration.html, то ссылки En и Ru также приведут к /registration.html. Предположительно, этот контроллер поддерживает GET, поэтому, когда вы нажимаете на ссылку и генерируете запрос GET, все работает.

После того, как вы разместили форму, ссылки En и Ru ведут к /user.html, потому что именно так вы запрограммировали страницу. Нажмите на эти ссылки, и вы сгенерируете запрос GET в /user.html. Предположительно, это терпит неудачу, потому что контроллер для /user.html поддерживает POST, но не GET.

К вашему сведению, вы можете точно видеть, что происходит, как на стороне клиента, так и на стороне сервера. В любом случае используйте любое количество инструментов для отслеживания трафика HTTP, идущего туда-сюда.

Скорее всего, вы используете Spring таким образом, что переключение языков происходит на стороне сервера, поэтому вам нужно снова получить реальную страницу. В частности, чтобы исправить вашу регистрационную форму, проще всего будет сбросить данные, которые пользователь уже ввел, и просто переключить ссылку, чтобы указать на /registration.html, даже если проверка формы не удалась. (Другими словами, ссылка НЕ ​​должна создаваться на основе того, какой URL привел вас на страницу.) Скорее всего, пользователь не будет переключать языки в середине. Однако, если вы должны хранить данные формы, требуется другой подход.

0 голосов
/ 12 сентября 2013

Я думаю, вы должны использовать POST / REDIRECT / GET patter.

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), который вызывается после перенаправления, вы можете использовать класс 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.

0 голосов
/ 23 июня 2011

Я исправил проблему, изменив отображение с

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

до

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

и ошибка исчезла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...