@ControllerAdvice Not Firing
我正在开发一个Spring MVC / Webflow应用程序(版本3.2)并试图让exception处理工作,我可以将自定义exception消息输出到日志文件和error.jsp。 我遇到的问题是exception处理程序没有被解雇。 我创建了下面的类,并将其注释为“ @ControllerAdvice
”,并将其放入与我的控制器相同的包中抛出exception:
@ControllerAdvice public class MyCustomExceptionController { @ExceptionHandler(MyCustomException.class) public ModelAndView handleMyException(MyCustomException ex) { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("/error/error"); modelAndView.addObject("errorId", ex.getErrorId()); modelAndView.addObject("message", ex.getErrorMessage()); return modelAndView; } }
并将以下内容添加到mvc-config文件中:
并在我的app-config文件中包含以下内容:
任何想法为什么这不起作用?
元素隐式注册ExceptionHandlerExceptionResolver
bean。 此类有一个initExceptionHandlerAdviceCache()
方法,该方法扫描上下文中的bean以查找其类类型使用@ControllerAdvice
注释的bean。
它通过首先调用ControllerAdviceBean.findAnnotatedBeans(ApplicationContext)
。 在内部,此方法使用ApplicationContext#getBeanDefinitionNames()
。 这种方法的javadoc说明
不考虑该工厂可能参与的任何层级
澄清这意味着什么。 在部署描述符中声明ContextLoaderListener
时,它会加载我们称为根或应用程序ApplicationContext
并使其在ServletContext
可用。 然后,当您声明DispatcherServlet
,它会创建自己的servlet ApplicationContext
并使用它在ContextLoaderListener
加载的ServletContext
属性中找到的任何ApplicationContext
作为该上下文的父级。 层次结构看起来像这样
Root ApplicationContext // loaded by the ContextLoaderListener | Servlet ApplicationContext // loaded by the DispatcherServlet
每个ApplicationContext
都可以访问父上下文中的bean,但不能相反。
上面的方法选择不在父上下文中使用bean,因此只能访问当前ApplicationContext
bean(真的是BeanFactory
)。
因此,如果你的
我将从app-config
名称中假设在根ApplicationContext
声明,但是
在servlet ApplicationContext
声明,再次假设从mvc-config
,然后查找@ControllerAdvice
bean的ExceptionHandlerExceptionResolver
将找不到任何。 它在servlet上下文中查找bean,但它们不存在,它们位于根上下文中。
如果其他人遇到这样的问题 – 我发现了一个错误。
我只有一个RequestMapping( http:// localhost:8080 / myapp / verify / verify )
在InterceptorController
,在PreHandle方法中,我显式抛出exception – > throw new MyCustomException("error","error.jsp")
来测试我的@ControllerAdvice
Exception
处理。
当我去http:// localhost:8080 / myapp /我会看到拦截器控制器被调用时,我的自定义exception被抛出,但是从未调用带有@ExceptionHandler(MyCustomException.class)
的@ControllerAdvice
类。
我添加了一个@RequestMapping(value="/")
,它解决了我的问题。 由于我试图转到没有与之关联的@RequestMapping
的URI,因此我得到了一个'NoHandlerFoundException'
,它将我的Exception
从冒泡中缩短了。
简而言之,确保您尝试调用的URI具有与之关联的@RequestMapping
,或者在ExceptionHandler
类中使用一个方法来处理NoHandlerFoundException
。
希望这可以帮助。