Spring中@JsonFormat验证失败的异常捕获与处理问题
@JsonFormat验证失败的异常捕获方案
一、抛出的异常类型
当@JsonFormat注解的字段反序列化失败时,Jackson会抛出InvalidFormatException(Jackson 2.x及以上版本),而Spring MVC会将这个原始异常包装为HttpMessageNotReadableException。这就是直接用@ExceptionHandler(Exception.class)无法捕获的核心原因——Spring在请求体解析阶段会先将Jackson异常包装,若全局异常处理器未明确处理这个包装类,就会被默认异常解析器拦截。
二、拦截处理方法
通过@ControllerAdvice修饰的全局异常处理器,明确捕获HttpMessageNotReadableException,并从中提取Jackson的原始异常做针对性处理:
1. 编写全局异常处理类
@ControllerAdvice public class RestExceptionHandler { @ExceptionHandler(HttpMessageNotReadableException.class) public ResponseEntity<ErrorResponse> handleInvalidFormatException(HttpMessageNotReadableException ex) { Throwable rootCause = ex.getCause(); if (rootCause instanceof InvalidFormatException) { InvalidFormatException invalidFormatEx = (InvalidFormatException) rootCause; // 获取错误字段名 String fieldName = invalidFormatEx.getPath().get(0).getFieldName(); // 获取非法输入值 String invalidValue = invalidFormatEx.getValue().toString(); // 构造错误提示(若需动态获取@JsonFormat的pattern,可通过反射实现) String errorMsg = String.format("字段「%s」的值「%s」不符合格式要求,期望格式为 yyyy-MM-dd HH:mm.SSS", fieldName, invalidValue); return ResponseEntity.badRequest().body(new ErrorResponse(errorMsg)); } // 处理其他请求体解析错误 return ResponseEntity.badRequest().body(new ErrorResponse("请求体格式非法")); } // 错误响应实体类 static class ErrorResponse { private String message; public ErrorResponse(String message) { this.message = message; } public String getMessage() { return message; } } }
2. 补充说明
- 若需要动态获取字段上
@JsonFormat的pattern,可通过反射实现:从InvalidFormatException的getTargetType()拿到实体类,再遍历字段找到对应注解的pattern值。 - 确保
@ControllerAdvice所在类被Spring容器扫描到(可通过@ComponentScan或默认包扫描规则实现)。
内容的提问来源于stack exchange,提问作者daniel-lopez
相关产品推荐
相关产品推荐

