@ControllerAdvice 不会因 Jackson 错误而触发
@ControllerAdvice not triggered for Jackson errors
我有一个 @RestController,它有一个 POST 方法,如果我在保存数据时出错,那么我的 @ControllerAdvice 就会触发;但是,如果我的错误是由@Valid 注释触发的Jackson 反序列化,它永远不会到达@ControllerAdvice。处理@Valid 异常的推荐方法是什么?
控制器方法:
@RequestMapping(method = RequestMethod.POST, value = "/principal/add")
public PrincipalDto addPrincipal(@Valid @RequestBody PrincipalDto
principal) {
return principalService.addPrincipal(principal);
}
异常控制器:
@ControllerAdvice(annotations = {RestController.class})
public class ExceptionController extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = Exception.class)
protected ResponseEntity<Object> handleExceptions(Exception ex, WebRequest
request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(ex);
return handleExceptionInternal(
ex, exceptionResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST,
request);
}
}
如果我尝试将无效数据传递给 LocalDate 字段,我在日志中看到的异常是:
Resolved exception caused by Handler execution:
org.springframework.http.converter.HttpMessageNotReadableException: JSON
parse error: Cannot deserialize value of type `java.time.LocalDate` from
String "string": Text 'string' could not be parsed at index 0; nested
exception is com.fasterxml.jackson.databind.exc.InvalidFormatException:
Cannot deserialize value of type `java.time.LocalDate` from String "string":
Text 'string' could not be parsed at index 0
at [Source: (PushbackInputStream); line: 10, column: 18] (through reference
chain: xxx.dto.PrincipalDto["dateOfBirth"])
我能够通过从 handleExceptions 方法中提取 handleExceptionInternal 来修复它:
@ControllerAdvice
public class ExceptionController extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = Exception.class)
protected ResponseEntity<Object> handleExceptions(Exception ex, WebRequest
request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(ex);
return handleExceptionInternal(
ex, exceptionResponse, new HttpHeaders(),
HttpStatus.BAD_REQUEST, request);
}
@Override
protected ResponseEntity<Object> handleExceptionInternal(
Exception ex, Object body, HttpHeaders headers, HttpStatus status,
WebRequest request) {
return new ResponseEntity<>(new ExceptionResponse(ex), headers, status);
}
}
我有一个 @RestController,它有一个 POST 方法,如果我在保存数据时出错,那么我的 @ControllerAdvice 就会触发;但是,如果我的错误是由@Valid 注释触发的Jackson 反序列化,它永远不会到达@ControllerAdvice。处理@Valid 异常的推荐方法是什么?
控制器方法:
@RequestMapping(method = RequestMethod.POST, value = "/principal/add")
public PrincipalDto addPrincipal(@Valid @RequestBody PrincipalDto
principal) {
return principalService.addPrincipal(principal);
}
异常控制器:
@ControllerAdvice(annotations = {RestController.class})
public class ExceptionController extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = Exception.class)
protected ResponseEntity<Object> handleExceptions(Exception ex, WebRequest
request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(ex);
return handleExceptionInternal(
ex, exceptionResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST,
request);
}
}
如果我尝试将无效数据传递给 LocalDate 字段,我在日志中看到的异常是:
Resolved exception caused by Handler execution:
org.springframework.http.converter.HttpMessageNotReadableException: JSON
parse error: Cannot deserialize value of type `java.time.LocalDate` from
String "string": Text 'string' could not be parsed at index 0; nested
exception is com.fasterxml.jackson.databind.exc.InvalidFormatException:
Cannot deserialize value of type `java.time.LocalDate` from String "string":
Text 'string' could not be parsed at index 0
at [Source: (PushbackInputStream); line: 10, column: 18] (through reference
chain: xxx.dto.PrincipalDto["dateOfBirth"])
我能够通过从 handleExceptions 方法中提取 handleExceptionInternal 来修复它:
@ControllerAdvice
public class ExceptionController extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = Exception.class)
protected ResponseEntity<Object> handleExceptions(Exception ex, WebRequest
request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(ex);
return handleExceptionInternal(
ex, exceptionResponse, new HttpHeaders(),
HttpStatus.BAD_REQUEST, request);
}
@Override
protected ResponseEntity<Object> handleExceptionInternal(
Exception ex, Object body, HttpHeaders headers, HttpStatus status,
WebRequest request) {
return new ResponseEntity<>(new ExceptionResponse(ex), headers, status);
}
}