如何自定义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
相关产品推荐
相关产品推荐

