@ExceptionHandler没有捕获MethodArgumentNotValidException

时间:2018-09-27 19:29:36

标签: java spring

我有以下@ControllerAdvice

@ControllerAdvice
public class ExceptionHandlingController {

    @ExceptionHandler(value = { MethodArgumentNotValidException.class,
            EntityExistsException.class, BadCredentialsException.class, MismatchedInputException.class })
    public ResponseEntity<ExceptionResponse> invalidInput(RuntimeException ex) {
        ExceptionResponse response = new ExceptionResponse();
        response.setErrorCode("BAD_REQUEST");
        response.setErrorMessage(ex.getMessage());
        return new ResponseEntity<ExceptionResponse>(response,
                HttpStatus.BAD_REQUEST);
    }

}

验证器以这种方式绑定到控制器:

@RestController
@RequestMapping("/api/authentication")
public class UserAccountControllerImpl implements UserAccountController {

    @Autowired
    private UserAccountService userAccountService;

    @Override
    public UserAccountEntity login(@Valid @RequestBody UserAccountEntity account,
            HttpServletResponse response) throws BadCredentialsException {
        return userAccountService.authenticateUserAndSetResponsenHeader(
                account.getUsername(), account.getPassword(), response);
    }

    @Override
    public UserAccountEntity create(@Valid @RequestBody UserAccountEntity userAccount,
            HttpServletResponse response) throws EntityExistsException {
        String username = userAccount.getUsername();
        String password = userAccount.getPassword();
        userAccountService.saveIfNotExists(username, password);
        return userAccountService.authenticateUserAndSetResponsenHeader(
                username, password, response);
    }

    //used to bind the validator to the incoming request
    @InitBinder
    public void binder(WebDataBinder binder) {
        binder.addValidators(new UserAccountValidator());
    }
}

这是UserAccountValidator,用于验证传入的UserAccountEntity

public class UserAccountValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return UserAccountEntity.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        UserAccountEntity userAccount = (UserAccountEntity) target;
        String password = userAccount.getPassword();
        String username = userAccount.getUsername();
        EmailValidator emailValidator = EmailValidator.getInstance();
        if (!emailValidator.isValid(username)) {
            errors.reject("Username must be a valid email address");
        }
        if (password.length() > 30 || password.length() < 8) {
            errors.reject("Password must be at least 8 and at most 30 characters");
        }
        if (!Pattern.compile( "[0-9]" ).matcher(password).find()) { // it doesn't contain any digit
            errors.reject("Password must have at least one digit");
        }
        if (password.toUpperCase().equals(password)) { //it's all upper-case
            errors.reject("Password must have at least one lower case character");
        }
        if (password.toLowerCase().equals(password)) { //it's all lower-case
            errors.reject("Password must have at least one upper case character");
        }
    }
}

当我输入无效的密码/用户名时,出现以下错误:

java.lang.IllegalStateException: Could not resolve method parameter at index 0 in public org.springframework.http.ResponseEntity<com.myproject.project.core.controller.ExceptionResponse> com.myproject.project.core.controller.ExceptionHandlingController.invalidInput(java.lang.RuntimeException): No suitable resolver for argument 0 of type 'java.lang.RuntimeException'
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:175) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]

为什么没有抓住MethodArgumentNotValidException

1 个答案:

答案 0 :(得分:2)

至少,异常MethodArgumentNotValidException不是RuntimeException,但是您可以在该异常处理程序中使用RuntimeException参数。 对于测试,将方法参数中的RuntimeException更改为Exception。