在Spring控制器中返回未捕获异常的JSON

时间:2016-06-27 20:14:27

标签: java json spring-mvc exception-handling spring-restcontroller

我有一个用@RestController注释的Spring控制器,它正在返回JSON。我还有一个带有@ControllerAdvice注释的类,其中@ExceptionHandler与一些自定义异常相关。我正在使用Tomcat来提供这个RESTful API。我希望有任何非自定义异常,例如来自第三方库或Nu​​llPointerException的异常被捕获并返回状态500 - 内部服务器错误为JSON,带有消息而不是显示错误的HTML页面。

如果我在控制器建议中使用@ExceptionHandler(Exception.class),它将接管所有Spring异常,如MissingPathVariableException.class,这是不理想的。我尝试过扩展Sp​​ring的ResponseEntityExceptionHandler,但是这个类没有用@ResponseBody注释,因此不会返回JSON。

  1. 如何在不影响Spring内部的情况下,在Spring RESTful API中为未捕获和未知的异常(无法计划的异常)返回JSON?
  2. 如果请求是否有异常,我怎样才能完全关闭返回HTML并确保只有JSON响应?

2 个答案:

答案 0 :(得分:4)

要在未捕获的异常上返回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异常处理的更多详细信息(使用代码示例)。

答案 1 :(得分:0)

HttpEntity表示一个HTTP请求或响应,由标题和 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 ,即您可以传递对象的确切位置希望在异常到达时作为http响应的正文