首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

为啥struts2控制台不打印出错信息

2012-08-31 
为什么struts2控制台不打印出错信息为什么struts2控制台不打印出错信息,我已经按照网上说的做了,还是不行。

为什么struts2控制台不打印出错信息
为什么struts2控制台不打印出错信息,我已经按照网上说的做了,还是不行。为什么,我需要知道原因。
(我使用的是struts2.2.1)
要彻底搞清楚这个问题得从struts2的核心机制说起:

struts2的核心机制是interceptor,首先,假设所有拦截器的模型都是是before()-->invoke()-->after(),(这样假设为了理清思路,抓住主要原因)
让我们来看struts的执行过程:

1、首先请求触发调用核心过滤器的doFilter。
2、调用Dispatcher的serviceAction()分发请求。
3、找到请求对应的action代理StrutsActionProxy,执行execute,从而执行DefaultActionInvocation的invoke(),
这里可以说是核心调用的开始。
4、DefaultActionInvocation中的invoke方法 判断请求的action是否配置interceptor,如果interceptors.hasNext()为true,则调用第一个interceptor,在interceptor中再调用invocation.invoke(),然后调用第二个interceptor,如此反复(递归)。(注意此处只是调用的interceptor的before()-->invoke(),还没有调用after()方法)
像这样从上至下(对应action的interceptor配置)调用所有interceptor,最后通过invokeAction()调用真正action的方法。
5、最后从第一个interceptor开始,从上至下依次执行interceptor的after()。

由此可以得出struts2的核心执行顺序是最先执行的最先退出,即FIFO

网上有几篇文章都认为控制台不显示异常,是因为ExceptionMappingInterceptor:
  @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        String result;

        try {
            result = invocation.invoke();
        } catch (Exception e) {
            if (isLogEnabled()) {
                handleLogging(e);
            }
            List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
            String mappedResult = this.findResultFromExceptions(exceptionMappings, e);
            if (mappedResult != null) {
                result = mappedResult;
                publishException(invocation, new ExceptionHolder(e));
            } else {
                throw e;
            }
        }

        return result;
    }

从代码中看出如果配置了handleLogging() ,就可以输出日志,这是没错,但是控制台还是不会有任何异常信息的。
只是因为在默认情况下(没有配置全局Exception的result),ExceptionMappingInterceptor会和其他的interceptor一样"throw e"。

接下来才是本文的重点,其实try…...catch…..finally 的捕捉过程也和struts2执行过程一样采取FIFO

那么也就是说如果从内至外的catch过程中,哪一步第一个e.printStackTrace(),不throw e,就会在哪一步看到控制台上输出异常。然而所有的interceptor默认情况下都throw e了,只有外层的Dispatcher的serviceAction()方法catch了,没有抛出,

catch (Exception e) {
            sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
        }

sendError方法最后在error.ftl显示了异常信息,(如果是ajax请求,那么连error.ftl都不会跳,一旦出错,除非配置日志或者在action中直接catch,否则将什么迹象都没有,相当棘手)终结了这个异常,试想一下如果这里没有catch,继续抛(直到tomcat),或者多一句e.printStackTrace(),我们都可以在java控制台上看到出错信息。


以上就是没法在控制台上打印出出错信息的根本原因。至于解决办法,只能手动在action中catch 并printStackTrace,

或者重写框架类。 1 楼 glchen 2011-04-07   刚看到另一个兄弟写的,发现不用手动在action中catch还是可以解决问题的http://tdcq.iteye.com/blog/706459
共同学习下吧, 嘿嘿...

热点排行