我有以下@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
?
答案 0 :(得分:2)
至少,异常MethodArgumentNotValidException不是RuntimeException,但是您可以在该异常处理程序中使用RuntimeException参数。 对于测试,将方法参数中的RuntimeException更改为Exception。