2015-06-09 91 views
2

我使用Spring(4.0.4)MVC构建RESTful API。我需要用一个错误的HTTP状态JSON表示返回ResponseEntity 404从404上的RESTful Spring API返回错误JSON(模糊@ExceptionHandler)

然而,当我做,结果在一个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> 

this stackoverflow post,我发现我可以防止这种错误页面由包括下列参数在web.xml中我

<init-param> 
    <param-name>throwExceptionIfNoHandlerFound</param-name> 
    <param-value>true</param-value> 
</init-param> 

并采用全球到位错误发送与此类似的建议:

@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); 
    } 
} 

然而,当我添加此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 

的问题是,它不知道是否要打电话给我定制的ExceptionHandler或定义的web.servlet。

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

回答

5

这就是我认为正在发生的事情:

@ControllerAdvice类扩展ResponseEntityExceptionHandler其中有一个方法handleNoHandlerFoundException(见这个文件在source code末)此外,你有一个@ExceptionHandler注解的方法来处理同样的例外。

@Override 
ResponseEntity handleNoHandlerFoundException(NoHandlerFoundException ex, 
      HttpHeaders headers, HttpStatus status, WebRequest request) 

我想他们都在你的代码导致这个问题。

因此,要么:

  1. 重写方法(和不使用@ExceptionHandler注解的方法)
  2. 不延伸ResponseEntityExceptionHandler。改为使用@ExceptionHandler批注的方法。

我认为这些选择应该工作。

+0

不幸的是,解决方案1和2都解决了我遇到的问题。 我认为问题在于ResponseEntityExceptionHandler类为NoHandlerFoundException定义了一个不能被覆盖的最终处理程序。 有没有人有任何其他建议,我可以如何返回与Spring REST的错误JSON或如何克服模糊的@ExceptionHandler问题? – greenJavaDev

+0

你说得对。我写了一些示例代码,并能够重现此问题。您是使用Spring Boot还是Spring MVC的常规Web应用程序? – Jigish

+0

Spring MVC webapp – greenJavaDev

0

试试这个。

package x.y.z; 

import org.springframework.http.HttpHeaders; 
import org.springframework.http.HttpStatus; 
import org.springframework.http.MediaType; 
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.ResponseBody; 
import org.springframework.web.bind.annotation.ResponseStatus; 
import org.springframework.web.servlet.NoHandlerFoundException; 

@ControllerAdvice 
public class MyExceptionHandler { 

    @ExceptionHandler(NoHandlerFoundException.class) 
    @ResponseStatus(value=HttpStatus.NOT_FOUND) 
    @ResponseBody 
    public ResponseEntity<String> handle404() { 
     HttpHeaders headers = new HttpHeaders(); 
     headers.setContentType(MediaType.APPLICATION_JSON_UTF8); 

     String json = "{\"error\":\"Resource not found.\"}"; 

     return new ResponseEntity<String>(json, headers, HttpStatus.NOT_FOUND); 
    } 
}