java - @ControllerAdvice 不触发

标签 java spring spring-mvc exception-handling

我正在开发一个 Spring MVC/Webflow 应用程序(版本 3.2)并尝试让异常处理工作,我可以在其中将自定义异常消息输出到日志文件和 error.jsp。我遇到的问题是异常处理程序没有被解雇。我创建了以下类并将其注释为“@ControllerAdvice”,并将其放入与抛出异常的 Controller 相同的包中:

@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 文件中:

<mvc:annotation-driven/>

并在我的应用程序配置文件中包含以下内容:

<context:component-scan base-package="package containing my controllers and MyCustomExceptionController">
        <context:include-filter type="annotation" 
    expression="org.springframework.web.bind.annotation.ControllerAdvice" />
    </context:component-scan> 

知道为什么这不起作用吗?

最佳答案

<mvc:annotation-driven/>元素隐式注册一个 ExceptionHandlerExceptionResolver bean 。这个类有一个 initExceptionHandlerAdviceCache()在上下文中扫描 bean 以查找其类类型用 @ControllerAdvice 注释的 bean 的方法.

它通过首先调用 ControllerAdviceBean.findAnnotatedBeans(ApplicationContext) 来完成此操作.在内部,此方法使用 ApplicationContext#getBeanDefinitionNames() .此方法的 javadoc 声明

Does not consider any hierarchy this factory may participate

澄清这是什么意思。当你声明一个 ContextLoaderListener在您的部署描述符中,它加载我们所说的根或应用程序 ApplicationContext并使其在 ServletContext 中可用.然后当你声明一个 DispatcherServlet ,它创建自己的 servlet ApplicationContext并使用任何 ApplicationContext它在 ServletContext 中找到ContextLoaderListener 加载的属性作为该上下文的父级。层次结构看起来像这样

Root ApplicationContext // loaded by the ContextLoaderListener
            |
Servlet ApplicationContext // loaded by the DispatcherServlet

每个 ApplicationContext可以访问父上下文中的 beans,但反之则不行。

上述方法选择不使用父上下文中的 bean,因此只能访问当前 ApplicationContext 中的 beans (BeanFactory 真的)。

因此,如果您的

<context:component-scan .../>

在根中声明 ApplicationContext正如我从名称 app-config 假设的那样, 但是

<mvc:annotation-driven />

在 servlet 中声明 ApplicationContext ,再次假设来自 mvc-config , 然后是 ExceptionHandlerExceptionResolver正在寻找 @ControllerAdvice bean 不会找到任何。它正在 servlet 上下文中寻找 bean,但它们不在那里,它们在根上下文中。

关于java - @ControllerAdvice 不触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21884737/

相关文章:

java - 用于测量 Java 代码的经验计算复杂性的工具?

java - 使用 FK "reuse"保存实体

java - 如何跳过 FlatFileItemReader<T> 中为空的特定列的值?

java - Android:将 httpURLConnection 连接到服务器

java - charAt().equals() 导致 "char cannot be dereferenced"

java - 前端jsp表单未绑定(bind)到模型: java. lang.ClassNotFoundException

java - 如何在 Controller 中映射两个不同的url : one url with param and the same without the param?

java - JWT 的 REST 安全性

java - Struts 2中使用ModelDriven接口(interface)时无法解析select标签中的list属性

当不在方法签名中时,Spring MockMVC 注入(inject) mockHttpServletRequest