Форма Spring MVC: ошибки не отображаются

Извиняюсь, если этот вопрос уже был задан. Я надеюсь, что кто-то может вмешаться и помочь мне понять, почему мои ошибки проверки формы не отображаются.

Я использую Spring 3.0.3 и Hibernate, и я использую проверку jsr-303 для проверки входных данных формы. У меня есть контроллер Spring, который обрабатывает GETting страницу, содержащую форму, созданную с помощью taglib формы Spring. В этой форме пользователь может изменить свое имя и сохранить его в базе данных. Если какой-либо из входных данных пуст, страница с формой должна снова отображаться с сообщениями об ошибках. Тот же контроллер обрабатывает отправку страницы. Кажется, что в большинстве случаев контроллер работает правильно, но когда в форме, отправленной пользователем, возникает ошибка, на странице ошибки не отображаются.

Вот как выглядит форма:

<form:form commandName="changeNameCommand">
    <form:errors path="*" cssClass="errorBox" />

    <table width="100%" border="0" cellspacing="5" cellpadding="5" align="left">
      <tr>
    <td><b>First Name:</b></td>
    <td><form:input path="firstName" value="${user.firstName}" /></td>
  </tr>
  <tr>
    <td><b>Last Name:</b></td>
    <td> <form:input path="lastName" value="${user.lastName}" /></td>
  </tr>
</table>
</form:form>    

Обратите внимание, что в представлении есть объект пользователя, который используется для заполнения формы текущими именем и фамилией пользователя. Это работает правильно.

Контроллер выглядит примерно так:

@Controller
@RequestMapping(value =  "/account/settings/change-name")
@SessionAttributes("changeNameCommand")
public class ChangeNameController {

    @ModelAttribute("changeNameCommand")
    public ChangeNameCommand getCommand() {
        return new ChangeNameCommand();
    }

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView getChangeNamePage(HttpServletRequest req) {
    ModelAndView mav = new ModelAndView("Account.ChangeName");
        mav.addObject("page_title", "Change Name");

        return mav;
    }

    @RequestMapping(method = RequestMethod.POST)
    public String doChangeName(
                @ModelAttribute("changeNameCommand") 
                    @Valid ChangeNameCommand command, 
                    BindingResult result, SessionStatus status) {

        if (result.hasErrors()) {
            return "redirect:/account/settings/change-name"; 
        }

    // Code here to persist updated user first and last name to database...        

        status.setComplete();

        return "redirect:/home";
    }
}

Я использую Tiles 2.1.2 для составления страниц и Urlrewrite 3.1.0, чтобы помочь сформировать удобные URL-адреса.

Класс ChangeNameCommand выглядит примерно так:

import org.hibernate.validator.constraints.NotEmpty;

public class ChangeNameCommand {

    @NotEmpty(message = "You must provide a first name.")
    private String firstName;

    @NotEmpty(message = "You must provide a last name.")
    private String lastName;

    @NotEmpty(message = "Your password is required to make changes.")
    private String currentPassword;

    // Getters and setters here...
}

При отладке я вижу, что если нет ввода ни имени, ни фамилии, экземпляр BindingResult действительно содержит ошибки. Меня беспокоит перенаправление при возникновении ошибки. Я видел здесь другие вопросы, которые просто возвращают имя представления вместо использования префикса перенаправления:. Я пробовал это, но (я думаю) из-за того, как я использую Urlrewrite и как настроено отображение моего сервлета, Spring возвращает ошибку. я пытался вернуться

/account/settings/change-name
/web/account/settings/change-name
/mywebsite/web/account/settings/change-name

но безрезультатно. FWIW, вот мое отображение сервлета:

<servlet-mapping>
    <servlet-name>mywebsite</servlet-name>
    <url-pattern>/web/*</url-pattern>
</servlet-mapping>

Любая помощь высоко ценится!


person richever    schedule 03.10.2010    source источник


Ответы (2)


использование redirect приводит к исчезновению всех атрибутов запроса (включая ошибки и всю модель). Поэтому не используйте перенаправление, не используйте сеанс для временного хранения данных и не используйте диалоги. Или придумать, как пользоваться чем-то вроде вспышки (собираюсь через некоторое время)

Другое дело — использование UrlRewriteFilter с spring-mvc нецелесообразно. У вас есть полный контроль над вашими красивыми REST-подобными URL-адресами только с помощью spring-mvc.

person Bozho    schedule 03.10.2010
comment
Спасибо Божо. Как я могу изменить свой код для хранения данных в сеансе? Я думал, что это уже происходит, но, очевидно, нет. Спасибо! - person richever; 03.10.2010

Вот как я решил свою проблему. Начнем с того, что я не хотел отказываться от использования UrlRewriteFilter и Tiles. Однако проблема с этим заключалась в том, что в случае ошибок я не мог просто вернуть путь, как указано в аннотации контроллеров RequestMapping. Ниже мое решение с удаленным перенаправлением в случае ошибок в doChangeName().

@Controller
@RequestMapping(value =  "/account/settings/change-name")
@SessionAttributes("changeNameCommand")
public class ChangeNameController {

    @ModelAttribute("changeNameCommand")
    public ChangeNameCommand getCommand() {        
        return new ChangeNameCommand();
    } 

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView getChangeNamePage() {
        ModelAndView mav = new ModelAndView("Account.ChangeName");
        mav.addObject("page_title", "Change Name");

        return mav;
    }

    @RequestMapping(method = RequestMethod.POST)
    public ModelAndView doChangeName(@ModelAttribute("changeNameCommand") @Valid ChangeNameCommand command, 
            BindingResult result, SessionStatus status) {

        if (result.hasErrors
            ModelAndView mav = new ModelAndView("Account.ChangeName");
            mav.addObject("page_title", "Change Name");

            return mav;
         }

        // Code here to persist updated user first and last name to database...         

        status.setComplete();

        RedirectView view = new RedirectView("/home");
        return new ModelAndView(view);        
    }
}

Спасибо всем, кто помог мне в этом!

person richever    schedule 09.10.2010