Spring MVC for Rest 服务如何在 Jackson 反序列化错误时自定义错误“消息”?
Posted
技术标签:
【中文标题】Spring MVC for Rest 服务如何在 Jackson 反序列化错误时自定义错误“消息”?【英文标题】:Spring MVC for Rest service how do I customize the error "message" when it's a Jackson deserialization error? 【发布时间】:2015-06-01 01:37:21 【问题描述】:我的 Spring Boot 应用程序中有一个带有单一方法的 RestController。此方法处理对 /foo url 的 POST 请求。它接受一个 ID 和一个 DTO 对象作为参数。 Jackson 正在反序列化 DTO 对象。我已将 @Valid 添加到 DTO 参数以验证正在传递的几个属性。我的问题在于当我为一个应该是 int 的字段传入一个字符串时。这会触发 HttpMessageNotReadableException 并且输出的“消息”包含内部对象表示信息,例如类和包名称。在对@Valid 进行休眠验证之前,此错误发生在某个地方的 Jackson 反序列化逻辑中。我可以在我的控制器中创建一个 @ExceptionHandler 注释方法来处理这些类型的异常,但是我必须手动制作 json 输出或坚持 Spring 使用来自 Jackson 的默认消息。
这是发生此异常时 Spring 输出的内容:
"timestamp": 1427473174263,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "Could not read JSON: Can not construct instance of int from String value 'SHOULDNT BE A STRING': not a valid Integer value\ at [Source: java.io.PushbackInputStream@34070211; line: 1, column: 3] (through reference chain: com.blah.foo.dto.CustomerProductPromotionDTO[\"productId\"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of int from String value 'SHOULDNT BE A STRING': not a valid Integer value\ at [Source: java.io.PushbackInputStream@34070211; line: 1, column: 3] (through reference chain: com.blah.foo.dto.CustomerProductPromotionDTO[\"productId\"])",
"path": "/customers/123456/promotions"
如何自定义“消息”字段?
【问题讨论】:
【参考方案1】:所以我想出了解决这个 Jackson 错误并仍然使用 Spring 的默认休息响应的最佳方法。我没有意识到您可以将@ExceptionHandler 与@ResponseStatus 一起用于这些非自定义异常类型。
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseStatus(value=HttpStatus.BAD_REQUEST, reason="There was an error processing the request body.")
public void handleMessageNotReadableException(HttpServletRequest request, HttpMessageNotReadableException exception)
LOGGER.error("\nUnable to bind post data sent to: " + request.getRequestURI() + "\nCaught Exception:\n" + exception.getMessage());
【讨论】:
【参考方案2】:上面的 Spring 输出来自 BasicErrorController
,它实现了 ErrorController
。所以你可以实现自定义ErrorController
来处理来自Spring框架的错误消息的格式。参考https://gist.github.com/jonikarppinen/662c38fb57a23de61c8b
【讨论】:
【参考方案3】:在你的Controller
中,可以添加自定义错误响应的方法:
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<?> handleMessageNotReadableException(
HttpServletRequest request,
HttpMessageNotReadableException e)
//Build your response and send it back
【讨论】:
以上是关于Spring MVC for Rest 服务如何在 Jackson 反序列化错误时自定义错误“消息”?的主要内容,如果未能解决你的问题,请参考以下文章
如何正确实现使用 Spring MVC\Boot 返回图像列表的 REST 服务?
如何访问 Spring MVC REST 控制器中的 HTTP 标头信息?
如何在 spring-mvc 中为 REST 查询提供对象列表?