@ControllerAdvice未触发Jackson错误

时间:2018-03-12 18:25:31

标签: java json exception jackson2

我有一个@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"])

1 个答案:

答案 0 :(得分:1)

我能够通过从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);
  }
}