Why Spring MVC does not allow to expose Model or BindingResult to an @ExceptionHandler?

后端 未结 6 2396
天命终不由人
天命终不由人 2021-02-12 18:32

Situation

I\'m trying to group the code that logs the exceptions and render a nice view in a few methods. At the moment the logic is sometime in the @RequestHand

6条回答
  •  梦谈多话
    2021-02-12 18:59

    As stated before you can raise an exception wrapping a binding result object in some method of your controller:

        if (bindingResult.hasErrors()) {
            logBindingErrors(bindingResult);
            //return "users/create";
            // Exception handling happens later in this controller
            throw new BindingErrorsException("MVC binding errors", userForm, bindingResult);
        }
    

    With your exception defined as illustrated here:

    public class BindingErrorsException extends RuntimeException {
        private static final Logger log = LoggerFactory.getLogger(BindingErrorsException.class); 
        private static final long serialVersionUID = -7882202987868263849L;
    
        private final UserForm userForm;
        private final BindingResult bindingResult;
    
        public BindingErrorsException(
            final String message, 
            final UserForm userForm, 
            final BindingResult bindingResult
        ) {
            super(message);
            this.userForm = userForm;
            this.bindingResult = bindingResult;
    
            log.error(getLocalizedMessage());
        }
    
        public UserForm getUserForm() {
            return userForm;
        }
    
        public BindingResult getBindingResult() {
            return bindingResult;
        }
    }
    

    Next you just have to extract the required information from the raised then caught exception. Here assuming you have a suitable exception handler defined on your controller. It might be in a controller advice instead or even elewhere. See the Spring documentation for suitable and appropriate locations.

    @ExceptionHandler(BindingErrorsException.class)
    public ModelAndView bindingErrors(
        final HttpServletResponse resp, 
        final Exception ex
    ) {
        if(ex instanceof BindingErrorsException) {
            final BindingErrorsException bex = (BindingErrorsException) ex;
            final ModelAndView mav = new ModelAndView("users/create", bex.getBindingResult().getModel());
            mav.addObject("user", bex.getUserForm());
            return mav;
        } else {
            final ModelAndView mav = new ModelAndView("users/create");
            return mav;            
        }
    }
    

提交回复
热议问题