Spring MVC for Rest服务如何在杰克逊反序列化错误时自定义错误“消息”?

时间:2015-03-27 16:26:15

标签: spring-mvc jackson spring-boot

我的Spring Boot应用程序中有一个带有单个方法的RestController。此方法处理对/ foo url的POST请求。它将ID和DTO对象作为参数。 DTO对象正在被杰克逊反序列化。我已将@Valid添加到DTO参数以验证传递的两个属性。我的问题在于我为一个应该是int的字段传入一个String。这会触发HttpMessageNotReadableException和"消息"输出包含内部对象表示信息,如类和包名称。在@Valid的hibernate验证之前,杰克逊反序列化逻辑中发生了这个错误。我可以在我的控制器中创建一个@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"
}

如何自定义"消息"领域?

3 个答案:

答案 0 :(得分:3)

所以我想出了我认为解决这个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());
}

答案 1 :(得分:0)

上面的Spring输出来自实现BasicErrorController的{​​{1}}。因此,您可以实现自定义ErrorController来处理来自Spring框架的错误消息的格式。请参阅https://gist.github.com/jonikarppinen/662c38fb57a23de61c8b

答案 2 :(得分:0)

在您的Controller中,您可以添加自定义错误响应的方法:

@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<?> handleMessageNotReadableException(
            HttpServletRequest request, 
            HttpMessageNotReadableException e) {

    //Build your response and send it back
}