简体   繁体   中英

How to intercept the error message when spring boot web binding?

I try to make user registration codes with spring boot web starter. First, these are registration form class including constraints.

@Data
public class RegisterForm {

    @NotBlank(message = "Not valid username.") // (1)
    @Size(min=2, max=30, message="minimum 2 and maximum 30") // (3)
    private String username;

    @NotBlank(message = "Not valid password") // (1)
    @Size(min=5, message = "minimum 5") // (3)
    private String password;

    @Size(max=50, message="maximum 50") // (3)
    private String fullname;

    @NotEmpty(message = "Not valid email") // (2)
    private String email;
}

And next codes are controller classes which bind User class and registration form class.

@RequestMapping(value="/users/register", method=RequestMethod.POST)
public String register(@Valid RegisterForm registerForm, Model model, BindingResult bindingResult) {
        if(!bindingResult.hasErrors()) {
            User user = new User();
            user.setUsername(registerForm.getUsername());
            user.setPassword(registerForm.getPassword());
            user.setEmail(registerForm.getEmail());
            user.setFullname(registerForm.getFullname());
            user.setRole(UserRole.USER);

            this.userService.register(user);

            return "redirect:/home";
        }

        return "/users/register";
    }

And Below codes are Error Controller class.

@RequestMapping("/error")
public String errorHandle(HttpServletRequest request) {
        Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
        if(status != null) {
            Integer statusCode = Integer.valueOf(status.toString());

            if(statusCode.equals(HttpStatus.BAD_REQUEST.value())) {
                return "/errors/400";
            } else if(statusCode.equals(HttpStatus.NOT_FOUND.value())) {
                return "/errors/404";
            } else if(statusCode.equals(HttpStatus.FORBIDDEN.value())) {
                return "/errors/403";
            } else if(statusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR.value())) {
                return "/errors/500";
            }
        }

        return "errors/default";
    }

And I make the error intentionally ,and then the error message are brought on the console like below and 400 exception is thrown with /error/400 html.

Field error in object 'registerForm' on field 'username': rejected value []; default message [minimum 2 and maximum 30]
Field error in object 'registerForm' on field 'username': rejected value []; default message [Not valid username]
Field error in object 'registerForm' on field 'email': rejected value []; default message [Not valid email]
Field error in object 'registerForm' on field 'password': rejected value []; default message [Not valid password]
Field error in object 'registerForm' on field 'password': rejected value [];default message [minimum 5]]

My issue is I have no idea how to send the field error of registerForm messages to /error/400 html so the user can confirm which field of registerForm violates the constraint. I want to know how field error of registerForm can be transferred to /error/400 html. Any idea, please.

first step: validate data in the controller like this

@RequestMapping(value="/users/register", method=RequestMethod.POST)
public String register(@Valid RegisterForm registerForm)......

sencond step: make a controller advice which catch the exceptions

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        //here you can use api of MethodArgumentNotValidException to do anything you want
        //e.getBindingResult(),e.getFieldErrors(),etc;
        // you can change the return type of Object
    }

You need to extends ResponseEntityExceptionHandler which provide centralized exception handling across all RequestMapping methods. This base class provides an ExceptionHandler method for handling internal Spring MVC exceptions. This method returns a ResponseEntity for writing to the response with a HttpMessageConverter message converter.

@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
   // All Exceptions Handler.
   @ExceptionHandler(Exception.class)
   public final ResponseEntity<ExceptionBean> handleAllExceptions(Exception ex, WebRequest request) {...}

   // Unique Constraint Violation Exception Handler.
   @ExceptionHandler(DataIntegrityViolationException.class)
   public final ResponseEntity<ExceptionBean> handleDataIntegrityViolationExceptions(DataIntegrityViolationException ex, WebRequest request) {...}

   // Custom Exceptions Handler.
   @ExceptionHandler(DomainException.class)
   public final ResponseEntity<ExceptionBean> handleDomainExceptions(DomainException ex, WebRequest request) {
        ExceptionBean exceptionBean = new ExceptionBean(new Date(), ex.getMessage(),
                request.getDescription(false));

        LOGGER.error(ex.getMessage(), ex);

        return new ResponseEntity<>(exceptionBean, HttpStatus.BAD_REQUEST);
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM