2012-02-17 43 views
6

目前我正試圖使用​​Spring MVC 3.1實現Post/Redirect/Get模式。什麼是保留和恢復模型數據+驗證錯誤的正確方法?我知道我可以在POST方法中使用RedirectAttributes保留模型和BindingResult。但是,從閃存範圍的GET方法中恢復它們的正確方法是什麼?使用Post/Redirect /獲取模式保存模型狀態

我也做了以下內容POST:

@RequestMapping(value = "/user/create", method = RequestMethod.POST) 
public String doCreate(@ModelAttribute("user") @Valid User user, BindingResult result, RedirectAttributes rA){ 

    if(result.hasErrors()){ 
     rA.addFlashAttribute("result", result); 
     rA.addFlashAttribute("user", user); 

     return "redirect:/user"; 
    } 

    return "redirect:/user/success"; 
} 

而下面來獲取用戶創建形式:

@RequestMapping(value = "/user", method = RequestMethod.GET) 
public ModelAndView showUserForm(@ModelAttribute("user") User user, ModelAndView model){ 

    model.addObject("user", user); 
    model.setViewName("userForm"); 

    return model; 
} 

這讓我在的情況下保持給定的用戶數據錯誤。但是,什麼是恢復錯誤的正確方法(BindingResult)我想與彈簧形式的標籤,以顯示他們在形式:

<form:errors path="*" /> 

除了這將是有趣如何從訪問閃存範圍get方法?

回答

3
public class BindingHandlerInterceptor extends HandlerInterceptorAdapter { 

    public static final String BINDING_RESULT_FLUSH_ATTRIBUTE_KEY = BindingHandlerInterceptor.class.getName() + ".flashBindingResult"; 

    private static final String METHOD_GET = "GET"; 
    private static final String METHOD_POST = "POST"; 


    @Override 
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 


     if(METHOD_POST.equals(request.getMethod())) { 

      BindingResult bindingResult = getBindingResult(modelAndView); 

      FlashMap outFlash = RequestContextUtils.getOutputFlashMap(request); 

      if(bindingResult == null || ! bindingResult.hasErrors() || outFlash == null) { 
       return; 
      } 

      outFlash.put(BINDING_RESULT_FLUSH_ATTRIBUTE_KEY, bindingResult); 

     } 

     Map<String, ?> inFlash = RequestContextUtils.getInputFlashMap(request); 

     if(METHOD_GET.equals(request.getMethod()) && inFlash != null && inFlash.containsKey(BINDING_RESULT_FLUSH_ATTRIBUTE_KEY)) { 

      BindingResult flashBindingResult = (BindingResult)inFlash.get(BINDING_RESULT_FLUSH_ATTRIBUTE_KEY); 

      if(flashBindingResult != null) { 

       BindingResult bindingResult = getBindingResult(modelAndView); 

       if(bindingResult == null) { 
        return; 
       } 

       bindingResult.addAllErrors(flashBindingResult); 

      } 

     } 

    } 

    public static BindingResult getBindingResult(ModelAndView modelAndView) { 

     if(modelAndView == null) { 
      return null; 
     } 

     for (Entry<String,?> key : modelAndView.getModel().entrySet()) { 
      if(key.getKey().startsWith(BindingResult.MODEL_KEY_PREFIX)) { 
       return (BindingResult)key.getValue(); 
      } 
     } 

     return null; 
    } 


} 
1

爲什麼不在綁定失敗後顯示更新表單,因此用戶可以嘗試重新提交表單?

對此的標準方法似乎是從POST處理程序方法返回更新窗體視圖。

if (bindingResult.hasErrors()) { 
    uiModel.addAttribute("user", user); 
    return "user/create"; 
} 

然後,您可以使用窗體:errors標籤顯示錯誤。

+5

這忽略了問題的整個觀點。他試圖避免在POST中返回屏幕,因爲瀏覽器如何處理髮布的表單。如果用戶點擊刷新,或返回表單重新發布,這可能導致狀態在服務器上被修改兩次。更好地使用get將它們重定向回原始形式。 – chubbsondubs 2012-08-31 21:31:00

0

什麼是從 閃光範圍

在GET方法恢復他們的正確方法,我不知道我理解你通過恢復他們的意思。重定向之前添加爲flash屬性的內容將在重定向後的模型中顯示。沒有什麼特別的,需要做的。我收集你想要問別的東西,但我不確定那是什麼。

正如phahn指出的,你爲什麼重定向錯誤?處理這個問題的常用方法是重定向成功。