我正在使用SpringMVC,我想在休息控制器上处理异常。 我的控制器通常在响应输出中写一个json,但是当发生异常时我无法捕获它并返回tomcat html页面。
如何根据请求中的“accept”参数捕获全局异常并返回适当的响应?
答案 0 :(得分:14)
@ControllerAdvice注释是Spring 3.2发行版中添加的新注释。来自reference docs:
使用@ControllerAdvice注释的类可以包含@ ExceptionHandler,@ InitBinder和@ModelAttribute方法,这些方法将应用于跨控制器层次结构的@RequestMapping方法,而不是声明它们的控制器层次结构。 @ControllerAdvice是一个组件注释,允许通过类路径扫描自动检测实现类。
示例:
@ControllerAdvice
class GlobalControllerExceptionHandler {
// Basic example
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
ErrorMessage handleException(FirstException ex) {
ErrorMessage errorMessage = createErrorMessage(ex);
return errorMessage;
}
// Multiple exceptions can be handled
@ExceptionHandler({SecondException.class, ThirdException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
ErrorMessage handleException() {
ErrorMessage errorMessage = createErrorMessage(...);
return errorMessage;
}
// Returning a custom response entity
@ExceptionHandler
ResponseEntity<ErrorMessage> handleException(OtherException ex) {
ErrorMessage errorMessage = createErrorMessage(...);
ResponseEntity<ErrorMessage> responseEntity = new ResponseEntity<ErrorMessage>(errorMessage, HttpStatus.BAD_REQUEST);
return responseEntity;
}
}
基本上,它允许您捕获指定的异常,创建自定义ErrorMessage
(这是Spring将根据Accept
标头序列化到响应主体的自定义错误类)并在此示例将响应状态设置为400 - Bad Request
。请注意,最后一个示例返回ResponseEntity(并且不使用@ResponseBody
注释),这允许您以编程方式指定响应状态和其他响应标头。有关@ExceptionHandler
的更多信息可以在reference docs或我前一段时间写的blog post中找到。
更新:根据评论添加了更多示例。
答案 1 :(得分:1)
另一种方法(我正在使用的)是创建一个全局异常处理程序并告诉Spring应该使用它。然后,您不必复制逻辑或扩展与使用@ExceptionHandler
注释控制器方法时必须执行的相同的基本控制器。这是一个简单的例子。
public class ExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse response, Object o, Exception e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // Or some other error code
ModelAndView mav = new ModelAndView(new MappingJackson2JsonView());
mav.addObject("error", "Something went wrong: \"" + e.getMessage() + "\"");
return mav;
}
}
在<something>-servlet.xml
中,您将其指定为您想要的exceptionResolver:
<!-- Define our exceptionHandler as the resolver for our program -->
<bean id="exceptionResolver" class="tld.something.ExceptionHandler" />
然后所有异常都将发送到您的Exceptionhandler,您可以在那里查看请求并确定如何回复用户。就我而言,我正在使用杰克逊。
答案 2 :(得分:0)
ExceptionHandler annotation正在做你想做的事。