从404上的RESTful Spring API返回错误JSON(不明确的@ExceptionHandler)

gre*_*Dev 3 rest spring exception-handling http-status-code-404

我正在使用Spring(4.0.4)MVC来构建RESTful API.我需要返回一个ResponseEntity,其中包含一个错误的JSON表示,其中http状态为404.

但是,当我发出导致404的请求而不是看到错误JSON时,我得到以下输出:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /project/api/resource/100 was not found on this server.</p>
<p>Additionally, a 503 Service Temporarily Unavailable
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body></html>
Run Code Online (Sandbox Code Playgroud)

这个stackoverflow帖子,我发现我可以通过在我的web.xml中包含以下参数来防止发送此错误页面代替错误

<init-param>
    <param-name>throwExceptionIfNoHandlerFound</param-name>
    <param-value>true</param-value>
</init-param>
Run Code Online (Sandbox Code Playgroud)

并使用类似于此的全局建议:

@ControllerAdvice
public class MyExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public ResponseEntity<ErrorResponse> requestHandlingNoHandlerFound(HttpServletRequest req,
            NoHandlerFoundException ex) {

        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setText("error response");
        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当我添加此MyExceptionHandler类时,我收到以下异常:

Caused by: java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.servlet.NoHandlerFoundException]: {public org.springframework.http.ResponseEntity com.rest.MyExceptionHandler.requestHandlingNoHandlerFound
Run Code Online (Sandbox Code Playgroud)

问题是它不知道是否要调用我的自定义ExceptionHandler或web.servlet中定义的那个.

如何解决此问题,以便我能够使用Spring从API返回JSON?

Jig*_*ish 6

这就是我的想法:

你的@ControllerAdvice类扩展ResponseEntityExceptionHandler有一个方法handleNoHandlerFoundException(参见源代码中此文件的末尾)另外,你有一个@ExceptionHandler注释方法来处理同一个异常.

@Override
ResponseEntity handleNoHandlerFoundException(NoHandlerFoundException ex,
            HttpHeaders headers, HttpStatus status, WebRequest request)
Run Code Online (Sandbox Code Playgroud)

我认为在您的代码中同时使用它们会导致此问题.

所以要么:

  1. 覆盖该方法(并且不要使用@ExceptionHandler带注释的方法)
  2. 不要扩展ResponseEntityExceptionHandler.请改用@ExceptionHandler注释方法.

我认为其中任何一个选项都应该有用.