【问题标题】:Change Spring Boots default JSON error response structure更改 Spring Boots 默认 JSON 错误响应结构
【发布时间】:2017-03-08 00:21:12
【问题描述】:

我有一个使用 Spring Boot 构建的 API。默认情况下,Spring 抛出错误时的默认 JSON 结构是;

{
  "timestamp": 1477425179601,
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/categoriess"
}

这种结构与在 API 中返回我自己的错误响应不同,因此我想更改 Spring 以使用与我自己相同的结构以保持一致性。

我的错误响应的结构是这样的;

{
    "errors": [
        {
            "code": 999404,
            "message": "The resource you were looking for could not be found"
        }
    ]
}

我该怎么做呢?我试过使用异常处理程序,但我无法找出正确的异常来设置它。我还想确保 Http 状态仍然正确返回为 404,或者任何错误(500 等)。

【问题讨论】:

    标签: spring-boot


    【解决方案1】:

    我又看了一遍,确实设法将一些对我有用的东西放在一起。

    @Bean
        public ErrorAttributes errorAttributes() {
            return new DefaultErrorAttributes() {
                @Override
                public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
                    Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);
    
                    Map<String, Object> error = new HashMap<>();
                    error.put("code", errorAttributes.get("status"));
                    error.put("message", errorAttributes.get("error"));
    
                    Map<String, Object> errorResponse = new HashMap<>();
                    errorResponse.put("errors", error);
    
                    return errorResponse;
                }
            };
        }
    

    这将返回以下 JSON 响应以及 spring 将要返回的任何标头/http 状态代码。

    {
      "errors": {
        "code": 404,
        "message": "Not Found"
      }
    }
    

    这似乎对 spring 生成的错误非常有效,而我自己的异常是在控制器中或在具有 ExceptionHandlers 的特定 ControllerAdmin 类中处理的。

    【讨论】:

      【解决方案2】:

      执行此类操作的一种可能方法是使用@ExceptionHandler 注释在控制器内创建处理程序方法。

      @RestController
      @RequestMapping(produces = APPLICATION_JSON_VALUE)
      public class MyController {
      
          @RequestMapping(value = "/find", method = GET)
          public Object find() {
              throw new UnsupportedOperationException("Not implemented yet!");
          }
      
          @ExceptionHandler
          public ErrorListModel handleException(Exception exception) {
              ExceptionModel exceptionModel = new ExceptionModel(1337, exception.getMessage());
      
              ErrorListModel list = new ErrorListModel();
              list.add(exceptionModel);
      
              return list;
          }
      
          private class ErrorListModel {
              private List<ExceptionModel> errors = new ArrayList<>();
      
              public void add(ExceptionModel exception) {
                  errors.add(exception);
              }
      
              public List<ExceptionModel> getErrors() {
                  return errors;
              }
          }
      
          private class ExceptionModel {
              private int code;
              private String message;
      
              public ExceptionModel(int code, String message) {
                  this.code = code;
                  this.message = message;
              }
      
              public int getCode() {
                  return code;
              }
      
              public String getMessage() {
                  return message;
              }
          }
      }
      

      私有类 ErrorListModelExceptionModel 只是帮助定义生成的 JSON 主体的外观,我假设您已经拥有自己的类似类。

      find 方法只是抛出一个异常供我们处理,它会被handleException 方法拦截,因为它带有@ExceptionHandler 注释。在这里,我们创建了一个ExceptionModel,使用来自原始异常的信息填充它,并将其添加到ErrorListModel,然后我们将其返回。

      This blog post 从 2013 年开始比我更好地解释了这些功能,它还提到了一个额外的选项,@ControllerAdvice。它基本上允许您在其他控制器中重用异常处理。

      【讨论】:

      • 谢谢。在我的项目中,我有一个带有 ControllerAdvice 注释的 ExceptionConntroller,我在其中放置了 ExceptionHandlers。我已经尝试创建一个异常处理程序,但遗憾的是我似乎无法捕捉到 Spring 标准的 404 Not Found 响应。我在上面尝试了您的示例,但它也没有捕捉到它。
      • 那么这篇文章可能会给你一些答案:stackoverflow.com/questions/28902374
      猜你喜欢
      • 2017-08-08
      • 2015-05-20
      • 2019-11-17
      • 2017-04-23
      • 2016-04-04
      • 2019-01-13
      • 2018-12-14
      • 1970-01-01
      相关资源
      最近更新 更多