You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自定义Jackson反序列化HttpMessageNotReadableException错误提示

自定义HttpMessageNotReadableException的错误提示内容

我懂你想要把Spring默认的JSON反序列化错误提示改成更清晰、贴合业务场景的格式。先看你当前的异常处理代码:

@ExceptionHandler(value = HttpMessageNotReadableException.class) 
public ResponseEntity<?> requestParseException(HttpMessageNotReadableException ex) { 
    String errMessage = messageService.getMessage(INVALID_JSON_DATA); 
    return ResponseEntity.status(BAD_REQUEST) 
        .body(new BadRequestException(errMessage).toString()); 
}

当前你收到的默认错误提示是:

Can not deserialize value of type int from String "asd": not a valid Integer value

而你希望改成这样的自定义格式:

Error in node: "Test". String "asd" can't be parse Integer value

解决方案思路

HttpMessageNotReadableException的底层其实是Jackson的JsonMappingException,我们需要从这个嵌套异常中提取出错误字段(node)、错误值和目标类型这些关键信息,再组装成自定义的提示语。

修改后的完整代码

@ExceptionHandler(value = HttpMessageNotReadableException.class)
public ResponseEntity<?> requestParseException(HttpMessageNotReadableException ex) {
    String errMessage;
    // 获取底层的Jackson反序列化异常
    Throwable rootCause = ex.getRootCause();
    if (rootCause instanceof JsonMappingException) {
        JsonMappingException jsonEx = (JsonMappingException) rootCause;
        // 获取错误的字段路径(比如"Test"),兜底处理避免空指针
        String fieldName = jsonEx.getReference() != null ? jsonEx.getReference().getFieldName() : "unknown";
        // 获取错误的输入值,兜底处理
        String invalidValue = jsonEx.getValue() != null ? jsonEx.getValue().toString() : "unknown";
        // 获取期望的目标类型,兜底处理
        String targetType = jsonEx.getTargetType() != null ? jsonEx.getTargetType().getSimpleName() : "target type";
        // 组装自定义错误消息
        errMessage = String.format("Error in node: \"%s\". String \"%s\" can't be parsed to %s value", 
                                  fieldName, invalidValue, targetType);
    } else {
        // 兜底处理,如果不是Jackson的异常,用原来的默认消息
        errMessage = messageService.getMessage(INVALID_JSON_DATA);
    }
    return ResponseEntity.status(BAD_REQUEST)
            .body(new BadRequestException(errMessage).toString());
}

代码说明

  • 首先通过ex.getRootCause()拿到底层的JsonMappingException,这是Jackson抛出的具体反序列化异常
  • 用getReference().getFieldName()获取出错的字段名(也就是你说的node)
  • 用getValue()获取用户输入的错误值(比如"asd")
  • 用getTargetType().getSimpleName()获取期望的类型(比如Integer)
  • 最后用String.format()拼接成你想要的格式,同时加了兜底逻辑,避免异常信息缺失时出现空指针

这样处理后,当用户输入错误类型的JSON字段时,就能得到你想要的友好错误提示了。

内容的提问来源于stack exchange,提问作者Aliaksei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:39:27