Spring-POST 후 리디렉션 (유효성 검사 오류 포함)
Spring <form:errors>
태그 를 통해 후속 GET에서 사용할 수 있도록 BindingResult를 "보존"하는 방법을 알아 내려고합니다 . 이 작업을 수행하려는 이유는 Google App Engine의 SSL 제한 때문입니다. HTTP를 통해 표시되는 양식이 있고 게시물이 HTTPS URL에 있습니다. 리디렉션이 아닌 전달 만하면 사용자에게 https://whatever.appspot.com/my/form URL이 표시됩니다. 나는 이것을 피하려고 노력하고 있습니다. 이것에 접근하는 방법에 대한 아이디어가 있습니까?
아래는 내가하고 싶은 일이지만을 사용할 때만 유효성 검사 오류가 표시됩니다 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 및 개체 (이 경우 Register)를 모두 추가합니다.
BindingResult의 경우 "org.springframework.validation.BindingResult. [Name of your ModelAttribute]"라는 이름을 사용합니다.
유효성을 검사하는 데 사용하는 개체의 경우 ModelAttribute의 이름을 사용합니다.
RedirectAttributes를 사용하려면이를 구성 파일에 추가해야합니다. 다른 것들 중에서 Spring에 새로운 클래스를 사용하라고 말하고 있습니다.
<mvc:annotation-driven />
이제 리디렉션하는 곳마다 오류가 표시됩니다.
@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";
}
Oscar의 멋진 답변 외에도 해당 RedirectAttributes
접근 방식을 따르고 있다면 실제로 modelAttribute
리디렉션 된 페이지로 전달되고 있음을 잊지 마십시오 . 즉, 컨트롤러에서 리디렉션 된 페이지에 대해 해당 modelAttribute의 새 인스턴스를 생성 하면 유효성 검사 오류가 손실됩니다 . 따라서 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 컨트롤러 에서 수정해야 할 것입니다 . 이것으로부터:
@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
}
I would question why you need the redirect. Why not just submit to the same URL and have it respond differently to a POST? Nevertheless, if you really want to do this:
@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";
}
Then in your "create" method:
model.put("register",session.getAttribute("register"));
model.put("org.springframework.validation.BindingResult.register",session.getAttribute("register"));
The problem is you're redirecting to a new controller, rather than rendering the view and returning the processed form page. You need to do something along the lines of:
String FORM_VIEW = wherever_your_form_page_resides
...
if (binding.hasErrors())
return FORM_VIEW;
I would keep the paths outside of any methods due to code duplication of strings.
The only way to persist objects between requests (ie a redirect) is to store the object in a session attribute. So you would include "HttpServletRequest request" in method parameters for both methods (ie, get and post) and retrieve the object via request.getAttribute("binding"). That said, and having not tried it myself you may need to figure out how to re-bind the binding to the object in the new request.
Another "un-nicer" way is to just change the browser URL using javascript
I don't know the exact issue with Google App Engine but using the ForwardedHeaderFilter may help to preserve the original scheme that the client used. This filter was added in Spring Framework 4.3 but some Servlet containers provide similar filters and the filter is self-sufficient so you can also just grab the source if needed.
Perhaps this is a bit simplistic, but have you tried adding it to your Model? I.e., include the Model in your method's arguments, then add the BindingResult to it, which is then available in your view.
model.addAttribute("binding",binding);
I think you may have to use a forward rather than a redirect (in my head I can't remember if a redirect loses the session or not — I could be wrong about this as I don't have any documentation handy, i.e., if you're not getting the BindingResult after adding it to the Model, try using a forward instead to confirm this).
참고URL : https://stackoverflow.com/questions/2543797/spring-redirect-after-post-even-with-validation-errors
'Program Tip' 카테고리의 다른 글
WPF 직사각형-상단 모서리 만 둥글게 (0) | 2020.11.30 |
---|---|
Python의 비공개 멤버 (0) | 2020.11.30 |
JavaScript는 버튼 클릭시 페이지를로드합니다. (0) | 2020.11.30 |
C # 5.0의 async-await 기능은 TPL과 어떻게 다릅니 까? (0) | 2020.11.30 |
Mac에서 PATH 변수 편집 (0) | 2020.11.29 |