Spring @ControllerAdvice的全局错误处理程序不起作用

时间:2013-12-04 04:41:41

标签: java spring error-handling spring-3

任何人都知道为什么以下代码无法捕获异常?

package org.rythmengine.spring.web.servlet.view;

import org.rythmengine.RythmEngine;
import org.rythmengine.exception.RythmException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class RythmExceptionHandler {

    RythmEngine engine;

    @Autowired
    public RythmExceptionHandler(RythmConfigurer conf) {
        this.engine = conf.getRythmEngine();
    }

    @ExceptionHandler(value = RythmException.class)
    public ModelAndView defaultErrorHandler(RythmException e) throws Exception {
        if (engine.mode().isProd()) {
            throw e;
        }
        ModelAndView mav = new ModelAndView();
        mav.addObject("exception", e);
        mav.setViewName("errors/500.html");
        return mav;
    }

}

1 个答案:

答案 0 :(得分:0)

发现了这个问题。它需要在配置文件中添加一行:

<context:component-scan base-package="org.rythmengine.spring.web.servlet.view"/>

还需要在@EnableWebMvc注释之外添加@ControllerAdvice注释。

但是我不能强迫用户在他们的配置中添加组件,或者我想让它对用户透明。因此,解决方案成为以下代码:

    if (engine.isDevMode()) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.scan("org.rythmengine.spring.web.servlet.view");
    }

到目前为止,这还不是结束。它成功捕获用户控制器代码中的Exception,但不是视图呈现过程中的异常。我正在寻找一种方法来添加HandlerInterceptor,以便它可以处理DispatcherServlet.triggerAfterCompletion(...)

中的错误

<强>更新

上述代码证明不起作用。最终的解决方案是将以下注释添加到任意类:

@Configuration
@ComponentScan("org.rythmengine.spring.web.servlet.view")

是的,现在我不需要用户将<context:component-scan ...>添加到他们的xml配置文件中。

关于渲染时异常处理,我在RythmView类内部缓存异常,以防在checkResource(Locale)调用时出现错误(通常是编译错误或解析错误),并在在renderMergedTemplateModel调用之后,我将检查是否存在缓存异常,如果有,则呈现异常屏幕,如下所示:

enter image description here

是的,开发人员友好的屏幕功能仅在您为RythmConfigurer将devMode设置为true(默认情况下为false)时才可用:

<bean id="rythmConfig" class="org.rythmengine.spring.web.servlet.view.RythmConfigurer">
    <property name="resourceLoaderPath" value="/WEB-INF/rythm/"/>
    <property name="outputRequestParameters" value="false"/>
    <property name="devMode" value="true"/>
</bean>