spring boot中各种数据不匹配如何处理jackson反序列化错误

Posted

技术标签:

【中文标题】spring boot中各种数据不匹配如何处理jackson反序列化错误【英文标题】:How to handle jackson deserialization error for all kinds of data mismatch in spring boot 【发布时间】:2019-02-11 05:51:18 【问题描述】:

我知道这里有一些类似的问题,关于如何解析 ENUM,如何解析自定义 JSON 结构。但在这里我的问题是,当用户提交的 JSON 与预期不符时,如何提供更好的消息。

这是代码:

@PutMapping
public ResponseEntity updateLimitations(@PathVariable("userId") String userId,
                                        @RequestBody LimitationParams params) 
  Limitations limitations = user.getLimitations();
  params.getDatasets().forEach(limitations::updateDatasetLimitation);
  params.getResources().forEach(limitations::updateResourceLimitation);
  userRepository.save(user);
  return ResponseEntity.noContent().build();

而我期望的请求正文是这样的:


  "datasets": "public": 10,
  "resources": "cpu": 2

但是当他们提交这样的内容时:


  "datasets": "public": "str", // <--- a string is given
  "resources": "cpu": 2

响应将在日志中显示如下内容:

400 JSON parse error: Cannot deserialize value of type `java.lang.Integer` from String "invalid": not a valid Integer value; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.lang.Integer` from String "invalid": not a valid Integer value

在 [Source: (PushbackInputStream); line: 1, column: 23](通过引用链:com.openbayes.api.users.LimitationParams["datasets"]->java.util.LinkedHashMap["public"])

但我想要的是更易读的信息。

我尝试将ExceptionHandler 用于com.fasterxml.jackson.databind.exc.InvalidFormatException,但它不起作用。

【问题讨论】:

***.com/questions/9080904/… 可能会帮助你 【参考方案1】:

以下错误处理方法对我有用。

@ExceptionHandler(HttpMessageNotReadableException.class)
    public ResponseEntity handleAllOtherErrors(HttpMessageNotReadableException formatException) 
        String error = formatException.getMessage().toString();
return new ResponseEntity(error, HttpStatus.BAD_REQUEST);

【讨论】:

【参考方案2】:

真正的例外是 org.springframework.http.converter.HttpMessageNotReadableException。 拦截它,它就会起作用。

public ResponseEntity<String> handle(HttpMessageNotReadableException e) 
    return ResponseEntity.badRequest().body("your own message" + e.getMessage());

【讨论】:

【参考方案3】:

您可以编写一个控制器通知来捕获异常并返回相应的错误响应。

这里是 Spring Boot 中控制器建议的示例:

@RestControllerAdvice
public class ControllerAdvice 
    @ExceptionHandler(InvalidFormatException.class)
    public ResponseEntity<ErrorResponse> invalidFormatException(final InvalidFormatException e) 
        return error(e, HttpStatus.BAD_REQUEST);
    

    private ResponseEntity <ErrorResponse> error(final Exception exception, final HttpStatus httpStatus) 
        final String message = Optional.ofNullable(exception.getMessage()).orElse(exception.getClass().getSimpleName());
        return new ResponseEntity(new ErrorResponse(message), httpStatus);
    


@AllArgsConstructor
@NoArgsConstructor
@Data
public class ErrorResponse 
    private String errorMessage;

【讨论】:

它对我不起作用。我无法得到 json 响应,似乎 InvalidFormatException 没有被处理。 您遇到错误了吗?调试应用程序时是否到达控制器建议上的代码? 不,它没有到达控制器建议中的代码,没有触发断点。 我只是想澄清一下,是否有任何可能被捕获的 try catch 子句? 我没有找到异常发生的地方...但我想可能你是对的。

以上是关于spring boot中各种数据不匹配如何处理jackson反序列化错误的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 如何处理 Hibernate 会话?

在 Spring Boot 中验证 JWT 时如何处理 InvalidSignatureException?

如何处理 Spring Boot 重定向到 /error?

如何处理 Spring Boot、AngularJS 应用程序中的 CORS 错误?

Spring Boot 如何处理可抛出对象

如何处理 Spring Boot Rest 和 Jackson Deserializer 的 Javax 验证中的无效数字