我正在开发一个具有自动配置和使用执行器的Spring Boot REST服务。当涉及异常层次时,spring(boot)如何处理异常处理?当一个例外扩展另一个例外时,@ExceptionHandler
可以用来发送一个不同的响应吗?
我有一个像这样定义的应用程序异常(我的异常扩展了RunTimeException,当然它扩展了Exception)。
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException() {
super();
}
public ResourceNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public ResourceNotFoundException(String message) {
super(message);
}
public ResourceNotFoundException(Throwable cause) {
super(cause);
}
}
我的REST服务控制器定义如下:
@RestController
@RequestMapping(value = "/sample")
public class SampleController extends AbstractRestHandler {
@RequestMapping(value="/test",
method = RequestMethod.GET,
produces = {"application/xml", "application/json"})
@ResponseStatus(HttpStatus.OK)
public @ResponseBody SampleTest getSampleTest(HttpServletRequest request, HttpServletResponse response) {
// for demo only -- to test exception handling
SampleTest s = null;
if (null==s) throw new ResourceNotFoundException();
return s;
}
控制器超类AbstractRestHandler定义了异常处理行为。当我的应用程序抛出(更具体的)ResourceNotFoundException时,我希望用NOT_FOUND
进行响应,我想用INTERNAL_SERVER_ERROR
响应任何其他异常。 (并且如上所示,ResourceNotFoundException间接地扩展了Exception)。问题是,即使抛出ResourceNotFoundException,应用程序也总是返回INTERNAL_SERVER_ERROR
(使用我的自定义“我搞砸了”主体)。
public abstract class AbstractRestHandler {
protected Logger log = LoggerFactory.getLogger(this.getClass());
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(ResourceNotFoundException.class)
public
@ResponseBody
RestErrorInfo handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request, HttpServletResponse response) {
log.info("Converting Resource Not Found exception to RestResponse : " + ex.getMessage());
return new RestErrorInfo(ex, "Sorry I couldn't find it :-(");
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public
@ResponseBody
RestErrorInfo handleGeneralException(Exception ex, WebRequest request, HttpServletResponse response) {
log.info("Converting Internal exception to RestResponse : " + ex.getMessage());
return new RestErrorInfo(ex, "I messed up.");
}
}
为了完整起见,这里是RestErrorInfo
public class RestErrorInfo {
public final String detail;
public final String message;
public RestErrorInfo(Exception ex, String detail) {
this.message = ex.getLocalizedMessage();
this.detail = detail;
}
}
非常感谢任何有关正确使用模式的帮助。