使用@ControllerAdvice统一处理参数校验的结果, 而不再使用BindingResult在Controller中处理
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@RestControllerAdvice
@Slf4j
public class ExceptionAdvice {
@ExceptionHandler(BindException.class)
public Object validExceptionHandler(BindException e){
FieldError fieldError = e.getBindingResult().getFieldError();
assert fieldError != null;
log.error(fieldError.getField() + ":" + fieldError.getDefaultMessage());
// 将错误的参数的详细信息封装到统一的返回实体
...
return ...;
}
}
感觉一下就方便不少,
但是, 如果你使用了@RequestBody @Valid 来封装参数并校验, 这个时候这个异常处理器又不起作用了...
{
"timestamp": "2018-09-17T07:27:36.152+0000",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"NotNull.person.id",
"NotNull.id",
"NotNull.java.lang.Integer",
"NotNull"
],
"arguments": [
{
"codes": [
"person.id",
"id"
],
"arguments": null,
"defaultMessage": "id",
"code": "id"
}
],
"defaultMessage": "不能为null",
"objectName": "person",
"field": "id",
"rejectedValue": null,
"bindingFailure": false,
"code": "NotNull"
}
],
"message": "Validation failed for object='person'. Error count: 1",
"path": "/post"
}
再添加一个异常处理器, 问题解决
@ExceptionHandler(MethodArgumentNotValidException.class)
public Object validExceptionHandler(MethodArgumentNotValidException e){
FieldError fieldError = e.getBindingResult().getFieldError();
assert fieldError != null;
log.error(fieldError.getField() + ":" + fieldError.getDefaultMessage());
...
return ...;
}