2010-03-30 2 views
50

스프링 <form:errors> 태그를 통해 후속 GET에서 사용할 수 있도록 BindingResult를 "보존"하는 방법을 파악하려고합니다. 그 이유는 Google App Engine의 SSL 제한 때문입니다. HTTP를 통해 표시되는 양식이 있고 해당 게시물은 HTTPS URL에 있습니다. 리디렉션이 아닌 전달 만하는 경우 사용자는 https://whatever.appspot.com/my/form URL을 볼 수 있습니다. 나는 이것을 피하려고 노력하고있다. 어떤 아이디어가 이것에 접근하는 방법?Spring - POST 후 재 지정 (유효성 검사 오류 포함)

아래에 나와있는 내용이 적용되지만 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"; 
} 

답변

-1

아마도 이것은 조금 단순하지만 모델에 추가 했습니까? 즉, 메서드의 인수에 Model을 포함시킨 다음 BindingResult를 추가하면 해당 뷰에서 사용할 수 있습니다.

model.addAttribute("binding",binding); 

나는 당신이 리디렉션 내가 가지고 있지 않는 한 이것에 대해 잘못 될 수 —를 세션을 잃거나하지 않으면 내가 기억할 수없는 내 머리에 (오히려 리디렉션보다 앞으로를 사용해야 할 것 같아요 만약 BindingResult를 Model에 추가 한 후에 BindingResult를 얻지 못한다면,이를 확인하기 위해 forward를 대신 사용해보십시오.)

+0

나는 이것을 나중에 시험해 볼 것이다. 그러나 내가 앞으로 나아가면 이미 잘 작동한다. 리디렉션 할 때 작동하도록 노력하고 있습니다. –

+0

Understanding, BindingResult를 추가 한 후에 실제로 볼 수 없다면 앞으로 만 제안했습니다. –

+0

방금 ​​시도했는데 여전히 리디렉션에서 작동하지 않습니다. –

1

보기를 렌더링하고 처리 된 양식 페이지를 반환하는 대신 새 컨트롤러로 리디렉션하고 있습니다.

String FORM_VIEW = wherever_your_form_page_resides 

... 

if (binding.hasErrors()) 
    return FORM_VIEW; 

문자열의 코드 중복으로 인해 경로가 외부에 유지됩니다.

+2

요점은 리디렉션을 수행하고 양식 오류를 표시하고 싶다는 것입니다. 내가 직접보기로 전달하면 제대로 작동합니다. –

+0

@ 루이스 : 고마워요. 이 솔루션은 내 문제에 도움이되었습니다. 개별 항목을 클릭 할 때 항목 목록을 반환하는 '게시물'이 있고 사용자가 다른 페이지 (세부 정보)로 리디렉션됩니다. 세부 정보 페이지에서 이전 페이지로 다시 리디렉션하고 싶습니다. 컨트롤러에 GET을 추가하고 앞서 설명한 모델을 초기보기로 전달했습니다. –

1

요청간에 개체를 지속시키는 유일한 방법은 (즉, 리디렉션) 개체를 세션 특성에 저장하는 것입니다. 따라서 두 메소드 (get 및 post)의 메소드 매개 변수에 "HttpServletRequest request"를 포함시키고 request.getAttribute ("binding")를 통해 객체를 검색합니다. 즉, 직접 시도하지 않고 새 요청에서 바인딩을 개체에 다시 바인딩하는 방법을 찾아야 할 수도 있습니다.

또 "유엔 좋네요"방법은 당신이 리디렉션이 필요한 이유 나는 질문 것 자바 스크립트

+0

당신의 제안 된 방법이 흥미 롭긴하지만 어떤 샘플 코드를 포함 할 수 있다면 더 좋을 것이라고 생각합니다. –

1

를 사용하여 브라우저 URL을 변경하는 것입니다. 왜 똑같은 URL에 복종하고 POST와 다르게 반응하지 않는가? 그럼에도 불구하고, 당신은 정말 이렇게 할 경우 : "만드는"방법 그리고

@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"; 
} 

:

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

메소드를 시도했지만 예외가 발생했습니다 : "요청 속성으로 사용할 수있는 bean 이름 'xxxx'에 대한 BindingResult 또는 일반 대상 객체가 없습니다" – user979051

+0

JSP에서 오류가 발생했을 가능성이 큽니다. http://www.mkyong.com/spring-mvc/spring-mvc-neither-bindingresult-nor-plain-target-object-for-bean-name-xxx-available-as-request-attribute/ – rjsang

+0

As 내 포인트는 모든 속성을 세션에 추가합니다 (필요한 경우 제외). FlashAttributes는 한 번 사용할 수 있으므로 세션보다 사용하는 것을 좋아합니다. 그러나 그것은 당신이 개발하는 측면에 달려 있습니다. 양식을 제출할 때 단일 JSP를 사용하고 JavaScript를 사용하지 않고 성공 또는 실패한 메시지를 표시 할 때 FlashAttributes를 사용합니다. –

59

봄 3.1 이후 당신은 RedirectAttributes를 사용할 수 있습니다. 리디렉션을 수행하기 전에 사용 가능하게 할 속성을 추가하십시오. 유효성을 검사하는 데 사용하는 BindingResult 및 개체 (이 경우 Register)를 모두 추가하십시오.

BindingResult의 경우 "org.springframework.validation.BindingResult. [name of your ModelAttribute]"라는 이름을 사용합니다.

유효성을 검사하는 데 사용되는 개체의 경우 ModelAttribute의 이름을 사용합니다.

RedirectAttributes를 사용하려면이 파일을 구성 파일에 추가해야합니다.당신이 오스카의 멋진 대답에 또

@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"; 
} 
+3

RedirectAttributes가 (더 이상 사용되지 않는?) ModelAndView 개념과 함께 작동하지 않는다는 점은 주목할 가치가 있습니다. 위의 예제에서와 같이 메서드는 간단한 문자열을 반환한다고 가정합니다. – kevinmrohr

+0

이 후 (내 경우) 특성이 리디렉션을 처리하는 컨트롤러 모델에 있지만 바인딩 결과에 오류가 없습니다. 오류 목록을 전달하고 다음과 같은 바인딩 결과에 추가해야했습니다. https://gist.github.com/OscarRyz/6381954 – OscarRyz

+2

오류가 발생하는 경우 : java.io.NotSerializableException : org.springframework. format.support.DefaultFormattingConversionService – Jens

45

을 리디렉션하는 곳이 있음을 다음과 같은 경우, 오류가 표시됩니다 이제

<mvc:annotation-driven /> 

: 무엇보다도 당신은 몇 가지 새로운 클래스를 사용하는 봄에 말하고있다 RedirectAttributes 접근 방식을 사용하면 실제로 modelAttribute을 리디렉션 된 페이지로 전달한다는 사실을 잊지 마십시오. 즉, 리디렉션 된 페이지 (컨트롤러에서)에 대한 modelAttribute의 새 인스턴스를 만들면 유효성 검사 오류가 손실됩니다.

@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 : 그래서 당신의 POST 컨트롤러 메소드는 다음과 같이 인 경우.

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

+0

이 문제가 해결되었습니다. 링크 된 기사가 더 잘 설명합니다. 감사. – adnans

+4

일반적인 함정 : "org.springframework.validation.BindingResult.register"의 "register"를 modelAttribute의 이름으로 변경하십시오 – borjab

+0

이것은 더 정확한 접근입니다 !!!!!!!! 나는이 대답을 보지 못했고 오스카에 대한 @Oscar 대답, 하나의 제안으로 고심하고있었습니다.이 답변을 답안에 추가하면 답변이 완료되고 아무도 내가 한 것처럼 고생 할 수 없습니다. :) 감사 인사들이 내 시간을 저장했습니다. –

0

나는 구글 앱 엔진과 정확한 문제를 알고하지 않습니다하지만 ForwardedHeaderFilter를 사용하여 원래의 구조를 유지하는 데 도움이 될 수 있다는 클라이언트가 사용되었습니다. 이 필터는 Spring Framework 4.3에서 추가되었지만 일부 서블릿 컨테이너는 유사한 필터를 제공하며 필터는 자동으로 필요하므로 필요할 경우 소스를 가져올 수 있습니다.

관련 문제