更改Spring Boots默认的JSON错误响应结构

时间:2016-10-25 19:57:22

标签: spring-boot

我有一个使用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等)。

2 个答案:

答案 0 :(得分:0)

执行此类操作的可能方法是使用@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,然后返回。

2013年的

This blog post比以往任何时候都更好地解释了这些功能,并且还提到了一个额外的选项,@ControllerAdvice。它基本上允许您在其他控制器中重用异常处理。

答案 1 :(得分:0)

我又看了一遍,并设法将一些适合我的东西放在一起。

@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生成的错误,而我自己的Exceptions我在控制器或具有ExceptionHandlers的特定ControllerAdmin类中处理。