应在@ControllerAdvice全局拦截HttpMessageNotReadableException,通过判断其cause是否为JsonParseException或JsonMappingException来区分JSON格式错误或映射失败,并返回结构化错误响应。

捕获 JSON 解析异常的常用位置
Spring MVC 中,@RequestBody 的 JSON 解析发生在 HttpMessageConverter 层(默认是 Jackson2ObjectMapper),异常通常在请求体反序列化阶段抛出,属于 HttpMessageNotReadableException 及其子类(如 JsonParseException、JsonMappingException)。这类异常不会进入 Controller 方法体,因此不能用 try-catch 直接包裹参数,而需在更上层统一拦截。
使用 @ControllerAdvice + @ExceptionHandler 全局处理
这是最推荐的方式,集中捕获所有控制器中因 JSON 解析失败导致的异常:
- 定义一个全局异常处理器类,添加 @ControllerAdvice 注解
- 用 @ExceptionHandler(HttpMessageNotReadableException.class) 拦截解析失败异常
- 内部可判断具体原因:检查异常的 cause 是否为 JsonParseException(格式错误,如逗号缺失、引号不闭合)或 JsonMappingException(字段类型不匹配、缺少构造器等)
- 返回结构化错误响应(如 400 Bad Request + 自定义 error message 或 code)
示例片段:
@ControllerAdvice
public class WebExceptionHandler {
<pre class='brush:java;toolbar:false;'>@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResponse handleJsonParseError(HttpMessageNotReadableException ex) {
Throwable cause = ex.getCause();
if (cause instanceof JsonParseException) {
return new ErrorResponse("JSON 格式错误", "INVALID_JSON_SYNTAX");
} else if (cause instanceof JsonMappingException) {
return new ErrorResponse("JSON 结构与目标类型不匹配", "MAPPING_FAILED");
} else {
return new ErrorResponse("请求体无法解析", "BAD_REQUEST");
}
}}
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
补充:启用 Jackson 详细错误信息(可选)
默认 Jackson 错误提示较简略。如需定位具体出错位置(如第 X 行第 Y 列),可在配置中开启:
- Spring Boot 项目:在 application.yml 中添加
spring:
jackson:
deserialization: fail-on-unknown-properties=false
# 更关键:让 Jackson 抛出带位置信息的异常(默认已开启,但确保未被覆盖)
- 若手动配置 ObjectMapper,确认未禁用 DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 或其他影响错误细节的设置
- 实际异常中,JsonParseException 的 getLocation() 方法可获取行/列号,可在异常处理器中提取并返回
注意边界情况:Content-Type 不匹配或空体
有些“解析失败”其实不是 JSON 问题:
- 客户端未设置 Content-Type: application/json → Spring 会跳过 Jackson 转换,直接报 HttpMediaTypeNotSupportedException,需单独捕获
- 请求体为空或仅空白字符 → Jackson 可能抛 JsonProcessingException,也属于 HttpMessageNotReadableException 的 cause,上述处理器已覆盖
- 编码问题(如含 BOM 的 UTF-8)→ 可能触发 IOException,作为 cause 出现在 HttpMessageNotReadableException 中,建议一并检查
不复杂但容易忽略

















