Spring Boot JSON解析异常处理需统一拦截HttpMessageNotReadableException,再通过getCause()识别InvalidFormatException或JsonParseException,提取字段、值、路径生成友好提示;关闭FAIL_ON_UNKNOWN_PROPERTIES避免未知字段报错;校验请求头与JSON合法性;统一响应结构封装错误信息。

Spring Boot 中处理 JSON 解析异常,核心是分清两类典型问题:一类是客户端传了非法 JSON(如语法错误、隐藏字符),触发 HttpMessageNotReadableException,返回 400;另一类是 JSON 字段合法但语义不匹配(如枚举值不存在、未知字段),需精准拦截并返回友好提示,避免暴露 Jackson 底层堆栈。
捕获顶层异常,别只盯 InvalidFormatException
很多人直接写 @ExceptionHandler(InvalidFormatException.class),结果不生效——因为 Spring 会先用更宽泛的 HttpMessageNotReadableException 拦住它,子类处理器根本没机会执行。
- 统一拦截
HttpMessageNotReadableException,再通过getCause()向下找真实原因 - 检查是否为
InvalidFormatException(枚举/类型转换失败)或JsonParseException(JSON 语法错误) - 提取字段名、非法值、路径信息,组装成前端可读的错误提示,比如:“status 字段不支持值 'UNK',请从 [ACTIVE, INACTIVE] 中选择”
忽略未知字段,避免 Unrecognized field 报错
前端多传了个字段,后端就 400?这不是业务问题,是配置问题。
- 全局关闭严格模式:在
@Configuration类中配置ObjectMapper,设FAIL_ON_UNKNOWN_PROPERTIES = false - 局部控制:在 DTO 类上加
@JsonIgnoreProperties(ignoreUnknown = true) - 慎用
@JsonAnyGetter/@JsonAnySetter,除非你真需要动态接收任意字段
规范请求体,提前拦截低级错误
很多 400 其实不是代码问题,而是请求本身有问题。
- 确认请求头含
Content-Type: application/json,否则 Spring 不走 Jackson 反序列化流程 - 用 JSONLint 或 VS Code 校验原始 JSON,排查不可见空格(U+00A0)、中文引号、换行符等隐藏字符
- Postman/curl 测试时手动重输 JSON,不复制网页或文档内容
统一响应结构,让错误也“有格式”
不要让前端收到一段 HTML 错误页或裸 JSON 堆栈。所有异常都应包装进标准 Result 或 ApiResponse。
- 定义统一响应体(推荐 Java 17
record),含code、message、data - 在
@RestControllerAdvice中,对不同异常返回对应code:400 类用UNPROCESSABLE_ENTITY(422),语义比 400 更准确 - 业务异常(如参数校验失败)抛
MethodArgumentNotValidException,和 JSON 解析异常分开处理,逻辑更清晰


















