我在特定控制器上添加了@ExceptionHandler方法。
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(HttpStatus.Not_FOUND)
public @ResponseBody doSomeThing(NullPointerException e) {...}
问题是:我也有一个习惯
org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver
在我的Rest Application(旧版)中定义为@Component。
现在,我的特定控制器中的@ExceptionHandler永远不会被调用。我需要支持两种异常处理策略。
如何配置spring 4.0.5,以便调用我的Controller中的@ExceptionHandler?
最佳答案
默认情况下,DispatcherServlet
将加载并注册HandlerExceptionResolver
中的所有ApplicationContext
实现,以帮助处理Controllers
中的异常。您会注意到AbstractHandlerExceptionResolver
类实现了Ordered
。在处理HandlerExceptionResolver
引发的异常时,大多数DispatcherServlet
实现都扩展了此类,并且HandlerExceptionResolver
使用它来排序Controllers
实现的列表。
您可能会怀疑,对@ExceptionHandler
上的Controllers
注释的处理也由HandlerExceptionResolver
实现来处理。准确地说:org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver
我的建议是,您的情况是HandlerExceptionResolver
对DispatcherServlet
的排序导致您的实现在AnnotationMethodHandlerExceptionResolver
之前被调用,这意味着您的@ExceptionHandler
注释将被有效忽略。
为了解决这个问题,我们需要做两件事:
AnnotationMethodHandlerExceptionResolver
直接注册为ApplicationContext
内的bean Order
值设置为大于自定义HandlerExceptionResolver
实现的值这意味着在处理
Exceptions
的Controllers
时,Spring将首先查看AnnotationMethodHandlerExceptionResolver
是否可以处理Exception,如果不能,则退回到您的自定义HandlerExceptionResolver
实现。作为在
HandlerExceptionResolver
上设置顺序的示例(假设您在某处使用XML配置):<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver" p:order="1" />
您可能还需要查看默认情况下向
HandlerExceptionResolver
注册的DispatcherServlet
实现的列表,并确定最适合您的应用程序的顺序。