
本文介绍如何在 Spring Boot 控制器中捕获并统一响应 JSON 请求体的语法错误(如非法 JSON 格式),避免暴露底层异常,通过 @ExceptionHandler 拦截 HttpMessageNotReadableException 并返回友好的客户端提示。
本文介绍如何在 spring boot 控制器中捕获并统一响应 json 请求体的语法错误(如非法 json 格式),避免暴露底层异常,通过 `@exceptionhandler` 拦截 `httpmessagenotreadableexception` 并返回友好的客户端提示。
在 Spring Boot Web 应用中,当客户端提交格式错误的 JSON(例如缺少引号、逗号错位、括号不匹配等),Spring MVC 默认会抛出 HttpMessageNotReadableException,并返回 400 Bad Request 及冗长的堆栈信息——这对前端不友好,也存在潜在的安全与可维护性风险。
最直接且推荐的解决方案是:全局异常处理器 + 精确异常类型拦截。你无需修改每个控制器方法,只需在 @ControllerAdvice 类中统一处理:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<ErrorResponse> handleHttpMessageNotReadable(
HttpMessageNotReadableException e, HttpServletRequest request) {
String message = "Invalid JSON format in request body";
// 可选:提取原始错误原因(需谨慎,避免泄露敏感信息)
String cause = Optional.ofNullable(e.getRootCause())
.map(Throwable::getMessage)
.filter(msg -> msg.length() < 200) // 防止过长日志
.orElse(message);
ErrorResponse error = new ErrorResponse(
HttpStatus.BAD_REQUEST.value(),
"BAD_REQUEST",
message,
request.getRequestURI()
);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
}配套的响应结构建议使用标准化错误对象,提升 API 一致性:
public record ErrorResponse(
int status,
String code,
String message,
String path
) {}✅ 关键优势说明:
- ✅ 解耦清晰:异常处理逻辑与业务逻辑完全分离;
- ✅ 全局生效:所有 @RequestBody 解析失败均被统一捕获,无需重复添加注解;
- ✅ 可控输出:可自定义状态码、错误码、消息及上下文(如请求路径);
- ✅ 安全可靠:避免直接暴露 Jackson 内部异常细节(如 JsonParseException 堆栈)。
⚠️ 注意事项:
- 不要仅依赖 @Valid 或 @RequestBody(required = true) —— 它们仅校验 Java 对象字段级约束(如 @NotNull),无法捕获 JSON 语法解析失败;
- HttpMessageNotReadableException 是 Spring MVC 在 HttpMessageConverter(如 MappingJackson2HttpMessageConverter)反序列化失败时抛出的顶层异常,务必精准捕获此类型;
- 若项目已集成 Spring Validation 全局异常处理(如 MethodArgumentNotValidException),请确保本 handler 的优先级或包扫描范围覆盖完整;
- 生产环境建议记录日志(含 traceId),但禁止将原始异常消息直接返回给客户端。
总结:@ExceptionHandler(HttpMessageNotReadableException.class) 是处理 JSON 语法错误最轻量、最标准、最可维护的方式。配合 @ControllerAdvice 和结构化错误响应,即可实现专业级的 API 错误体验。


















