Spring – redirect после POST (даже с ошибками проверки)

Я пытаюсь выяснить, как «сохранить» BindingResult, чтобы он мог использоваться в последующем GET через

Spring

. Причина, по которой я хочу это сделать, связана с ограничениями SSL для Google App Engine. У меня есть форма, которая отображается через HTTP, а сообщение – URL-адрес HTTPS. Если я только переадресую, а не перенаправляю, тогда пользователь увидит URL https://whatever.appspot.com/my/form . Я пытаюсь избежать этого. Любые идеи, как подойти к этому?

Ниже я хотел бы сделать это, но я вижу только ошибки проверки, когда я использую return "create" .

 @RequestMapping(value = "/submit", method = RequestMethod.POST) public final String submit( @ModelAttribute("register") @Valid final Register register, final BindingResult binding) { if (binding.hasErrors()) { return "redirect:/register/create"; } return "redirect:/register/success"; } 

Начиная с Spring 3.1 вы можете использовать RedirectAttributes. Добавьте атрибуты, которые вы хотите иметь, перед выполнением перенаправления. Добавьте в этот регистр как BindingResult, так и объект, который вы используете для проверки.

Для BindingResult вы будете использовать имя: “org.springframework.validation.BindingResult. [Имя вашего ModelAttribute]”.

Для объекта, который вы используете для проверки, вы будете использовать имя ModelAttribute.

Чтобы использовать RedirectAttributes, вы должны добавить это в свой файл конфигурации. Среди прочего вы рассказываете Spring, чтобы использовать несколько новых classов:

  

Теперь ошибки будут отображаться везде, где вы перенаправляете

 @RequestMapping(value = "/submit", method = RequestMethod.POST) public final String submit(@ModelAttribute("register") @Valid final Register register, final BindingResult binding, RedirectAttributes attr, HttpSession session) { if (binding.hasErrors()) { attr.addFlashAttribute("org.springframework.validation.BindingResult.register", binding); attr.addFlashAttribute("register", register); return "redirect:/register/create"; } return "redirect:/register/success"; } 

В дополнение к приятному ответу Оскара, если вы выполняете подход RedirectAttributes , не забывайте, что вы фактически передаете modelAttribute на перенаправленную страницу. Это означает, что если вы создадите новый экземпляр этого атрибута modelAttribute для перенаправленной страницы (в controllerе), вы потеряете ошибки проверки . Итак, если ваш метод controllerа POST выглядит примерно так:

 @RequestMapping(value = "/submit", method = RequestMethod.POST) public final String submit(@ModelAttribute("register") @Valid final Register register, final BindingResult binding, RedirectAttributes attr, HttpSession session) { if (binding.hasErrors()) { attr.addFlashAttribute("org.springframework.validation.BindingResult.register", binding); attr.addFlashAttribute("register", register); return "redirect:/register/create"; } return "redirect:/register/success"; } 

Тогда вам, вероятно, понадобится сделать модификацию в вашем регистре, чтобы создать страницу GET- controllerа. Из этого:

 @RequestMapping(value = "/register/create", method = RequestMethod.GET) public String registerCreatePage(Model model) { // some stuff model.addAttribute("register", new Register()); // some more stuff } 

в

 @RequestMapping(value = "/register/create", method = RequestMethod.GET) public String registerCreatePage(Model model) { // some stuff if (!model.containsAttribute("register")) { model.addAttribute("register", new Register()); } // some more stuff } 

Источник: http://gerrydevstory.com/2013/07/11/preserving-validation-error-messages-on-spring-mvc-form-post-redirect-get/

Проблема в том, что вы перенаправляетесь на новый controller, вместо того, чтобы отображать представление и возвращать страницу обработанной формы. Вам нужно что-то сделать в соответствии с:

 String FORM_VIEW = wherever_your_form_page_resides ... if (binding.hasErrors()) return FORM_VIEW; 

Я бы сохранил пути вне любых методов из-за дублирования кода строк.

Единственный способ сохранить объекты между запросами (например, redirect) – это сохранить объект в атрибуте сеанса. Таким образом, вы должны включить «запрос HttpServletRequest» в параметры метода для обоих методов (т. Е. Получить и отправить) и получить объект через request.getAttribute («привязка»). Тем не менее, и не пробовав это самостоятельно, вам может понадобиться выяснить, как повторно привязать привязку к объекту в новом запросе.

Еще один «неприемлемый» способ – просто изменить URL-адрес браузера с помощью javascript

Я бы поставил под вопрос, зачем вам redirect. Почему бы просто не отправить на тот же URL-адрес и ответить на него по-разному? Тем не менее, если вы действительно хотите это сделать:

 @RequestMapping(value = "/submit", method = RequestMethod.POST) public final String submit( @ModelAttribute("register") @Valid final Register register, final BindingResult binding, HttpSession session) { if (binding.hasErrors()) { session.setAttribute("register",register); session.setAttribute("binding",binding); return "redirect:/register/create"; } return "redirect:/register/success"; } 

Затем в вашем методе «create»:

 model.put("register",session.getAttribute("register")); model.put("org.springframework.validation.BindingResult.register",session.getAttribute("register")); 

Я не знаю точной проблемы с Google App Engine, но использование ForwardedHeaderFilter может помочь сохранить исходную схему, используемую клиентом. Этот фильтр был добавлен в Spring Framework 4.3, но некоторые контейнеры Servlet предоставляют аналогичные фильтры, и фильтр является самодостаточным, поэтому вы также можете просто захватить источник, если это необходимо.

Возможно, это немного упрощенно, но попробовали ли вы добавить его в свою модель? Т.е., включите модель в аргументы вашего метода, а затем добавьте BindingResult к ней, которая затем будет доступна в вашем представлении.

 model.addAttribute("binding",binding); 

Я думаю, вам, возможно, придется использовать переадресацию, а не redirect (в моей голове я не могу вспомнить, проиграет ли переадресация сессии или нет), я могу ошибаться в этом, так как у меня нет никакой документации, вы не получаете BindingResult после добавления его в модель, попробуйте использовать forward вместо этого, чтобы подтвердить это).

  • Инструмент проверки XML-схемы (XSD)?
  • Убедитесь, что вход в UITextField только числовой
  • Установить проверку classа для динамического текстового поля в таблице
  • Определите, является ли строка C допустимым int в C
  • Проверка даты с помощью проверки подлинности ASP.NET
  • JSF не поддерживает проверку кросс-поля, есть ли обходной путь?
  • PrimeFaces валидатор не запущен
  • загрузка jquery дважды вызывает ошибку?
  • jQuery: какой лучший способ ограничить «число» - только вход для текстовых полей? (разрешить десятичные точки)
  • Проверка верстки ViewModel для списка
  • В ответ на вопрос, как добавить сообщение об ошибке в сводку проверки?
  • Давайте будем гением компьютера.