【问题标题】:How to handle jackson deserialization error for all kinds of data mismatch in spring bootspring boot中各种数据不匹配如何处理jackson反序列化错误
【发布时间】: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,但它不起作用。

【问题讨论】:

标签: java spring-mvc spring-boot exception-handling jackson


【解决方案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 子句?
      • 我没有找到异常发生的地方...但我想可能你是对的。
      猜你喜欢
      • 2018-05-19
      • 2012-02-23
      • 1970-01-01
      • 1970-01-01
      • 2017-09-09
      • 1970-01-01
      • 2019-04-03
      • 2018-01-24
      • 2021-03-31
      相关资源
      最近更新 更多