Preserving model state with Post/Redirect/Get pattern

前端 未结 3 1602
名媛妹妹
名媛妹妹 2021-02-15 16:08

At the moment I am trying to implement the Post/Redirect/Get pattern with Spring MVC 3.1. What is the correct way to preserve and recover the model data + validation errors? I k

相关标签:
3条回答
  • 2021-02-15 16:32

    what is the correct way of recovering them in the GET method from the flash scope

    I'm not sure I understand what you mean by recovering them. What you add as flash attributes before the redirect will be in the model after the redirect. There is nothing special that needs to be done for that. I gather you're trying to ask something else but I'm not sure what that is.

    As phahn pointed out why do you redirect on error? The common way to handle this is to redirect on success.

    0 讨论(0)
  • 2021-02-15 16:48
    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;
        }
    
    
    }
    
    0 讨论(0)
  • 2021-02-15 16:49

    Why don't you show the update form after the binding fails, so the user can try to resubmit the form?

    The standard approach for this seems to be to return the update form view from the POST handler method.

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

    You can then display errors with the form:errors tag.

    0 讨论(0)
提交回复
热议问题