2

我正在使用 SpringMVC,我想处理休息控制器上的异常。我的控制器通常在响应输出中写入一个 json,但是当发生异常时我无法捕获它并返回 tomcat html 页面。

如何捕获全局异常并根据请求中的“接受”参数返回适当的响应?

4

3 回答 3

14

@ControllerAdvice注解是 Spring 3.2 版本中添加的一个新注解。从参考文档

使用@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可以在参考文档或我前段时间写的博客文章中找到有关 的更多信息。

更新:根据评论添加了更多示例。

于 2013-04-30T15:36:41.997 回答
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您将其分配为您想要的异常解析器:

<!-- Define our exceptionHandler as the resolver for our program -->
<bean id="exceptionResolver" class="tld.something.ExceptionHandler" />

然后所有异常都将发送到您的异常处理程序,您可以在那里查看请求并确定您应该如何回复用户。就我而言,我正在使用杰克逊。

于 2013-04-30T15:46:56.703 回答
0

ExceptionHandler 注释正在做你想要的。

于 2013-04-30T15:16:00.773 回答