Spring Validator和BindingResult - 如何设置不同的HttpStatus代码?

时间:2015-08-03 06:14:35

标签: spring validation api rest spring-mvc

亲爱的春天社区,

我正在使用Spring构建我的项目。在我的API层中,我正在利用 Validator 接口来进行一些自定义验证并设置错误。

@Override
public void validate(Object obj, Errors e) {

    SignUpRequest signUpRequest = (SignUpRequest) obj;
    User user = userService.getUserByEmail(signUpRequest.getEmail());

    if (user != null) {
        e.rejectValue("user", ErrorCodes.USER_EXIST, "user already exist");
    }
}

现在,在我的API签名中,因为我使用 BindingResult 对象,所以在我拥有的 @ControllerAdvice 中,如果用户为属性提供空值我的DTO对象,我将无法进入 @ExceptionHandler(MethodArgumentNotValidException.class)

这意味着,我无法为所提供的任何空值抛出HttpStatus.BAD_REQUEST。 在我的验证器的上述情况下,它不是HttpStatus.BAD_REQUEST,而是HttpStatus.OK。所以我的问题是,如何根据我从验证器获得的错误提供不同的HttpStatus类型?还有一种方法可以让我的@ExceptionHandler(MethodArgumentNotValidException.class)中的@ControllerAdvice仍然可以获取空值,并且还可以通过bindingResult获取其他自定义验证吗?

我希望我对这个问题很清楚。感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

好的,我相信我想出了解决方案! 为了根据您的错误类型抛出不同的HttpStatus,您需要具有自定义异常。然后在Validator中抛出自定义异常。您的ControllerAdvice应该注册以获取自定义异常并相应地对其进行操作。

例如,Validator应该具有以下内容:

if (!matcher.matches()) {
        e.rejectValue("email", ErrorCodes.EMAIL_INVALID, "email address is invalid");
        throw new BadRequestException("email address is invalid", e);
    }

    User user = userService.getUserByEmail(signUpRequest.getEmail());
    if (user != null) {
        e.rejectValue("email", ErrorCodes.USER_EXIST, "user already exist");
        throw new ValidationException("User Exist", e);
    }

控制器建议应该:

@ExceptionHandler(ValidationException.class)
@ResponseBody
public ResponseEntity<Map<String, Object>> handleValidationException(
        ValidationException validationException) {

    Map<String, Object> result = createErrorResponse(validationException.getErrors());
    return new ResponseEntity<Map<String, Object>>(result, HttpStatus.OK);
}

@ExceptionHandler(BadRequestException.class)
@ResponseBody
public ResponseEntity<Map<String, Object>> handleBadRequestException(
        BadRequestException badRequestException) {

    Map<String, Object> result = createErrorResponse(badRequestException.getErrors());
    return new ResponseEntity<Map<String, Object>>(result, HttpStatus.BAD_REQUEST);
}

这样,你可以根据你所犯的错误类型返回不同的HttpStatus。