Return JSON 关于 Spring 控制器中未捕获的异常

Return JSON on uncaught exceptions in Spring controllers

我有一个用 @RestController 注释的 Spring 控制器,它正在 returning JSON。我还有一个用 @ControllerAdvice 注释的 class,其中 @ExceptionHandler 与一些自定义异常相关。我正在使用 Tomcat 来提供这个 RESTful API。我想要任何非自定义异常,例如来自第三方库的异常或 NullPointerException 被捕获并 returned with status 500 - Internal Server Error as JSON with a message instead of显示错误的 HTML 页面。

如果我在控制器建议中使用 @ExceptionHandler(Exception.class),它会接管所有 Spring 异常,例如 MissingPathVariableException.class,这并不理想。我试过扩展 Spring 的 ResponseEntityExceptionHandler 但是这个 class 没有用 @ResponseBody 注释所以 return JSON.

  1. 你如何 return JSON 在 Spring RESTful API 中处理未捕获和未知的异常(你无法计划的异常)影响 Spring 的内部结构?
  2. 如何完全关闭 returning HTML 并确保无论请求是否有异常都只有 JSON 响应?

要在未捕获的异常上返回 JSON,您可以使用此代码:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;

@ControllerAdvice  
@RestController
public class GlobalExceptionHandler {

    private class JsonResponse {
        String message;

        public JsonResponse() {
        }

        public JsonResponse(String message) {
            super();
            this.message = message;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }       
    }

    @ExceptionHandler(value = Exception.class)  
    public ResponseEntity<JsonResponse> handleException(Exception e) {
        return new ResponseEntity<JsonResponse>(new JsonResponse(e.getMessage()), HttpStatus.BAD_REQUEST);
    }

}

JSON 如果抛出异常则结果:

{
    "message": "Something wrong!"
}

您可以使用此 link 获取有关 Spring 异常处理(带有代码示例)的更多详细信息。

HttpEntity表示一个HTTP请求或响应,由headers和body.

组成
// Only talks about body & headers, but doesn't talk about status code
public HttpEntity(T body, MultiValueMap<String,String> headers)

ResponseEntity 扩展了 HttpEntity 但也添加了一个 Http 状态代码。

// i.e ResponseEntity = HttpEntity + StatusCode
public ResponseEntity(T body, MultiValueMap<String,String> headers, HttpStatus statusCode)

因此用于完全配置 HTTP 响应。

如果您查看 ResponseEntity 的构造函数,您将看到第一个参数为 body,即您的确切位置可以传递你想要的object作为异常到达时的http响应body