关于SSH中异常处理的冲突引起的无限循环-Infinite recursion detected: [……]-问题处理

来源:互联网 发布:淘宝免费申请试用理由 编辑:程序博客网 时间:2024/06/05 16:12

关于SSH异常处理的冲突引起的无限循环-Infinite recursion detected: [……]-问题处理

项目相关架构版本信息 - Spring4+Hibernate4+Struts2.5

先将异常处理说明如下 -

1、Spring的异常处理

采用切面类的AOP编程完成相关处理

<bean id="exceptionAspect" class="fjw.spring.aop.xml.aspect.exception.ExceptionAspect">        <property name="order" value="20"/>    </bean>    <aop:aspect ref="exceptionAspect">        <aop:after-throwing method="exceptionAdvice" pointcut-ref="commonPC" throwing="aimMethodException"/>    </aop:aspect>

会完成异常信息的相关处理

2、Struts2的异常处理

        <!-- 声明默认的全局结果集 -->        <global-results>            <result name="errorHandler" type="chain">                <param name="actionName">errorProcessor</param>            </result>        </global-results>        <global-exception-mappings>            <!-- 添加配置一个Struts2的全局异常的结果处理器 -->            <exception-mapping exception="java.lang.Throwable"            result="errorHandler" />        </global-exception-mappings>        <action name="errorProcessor" class="fjw.struts2.web.action.ErrorProcessor">            <!-- 采用上述的默认的全局结果集是不行的 - 这里针对的是成功的返回  -->            <result>/error.jsp</result>        </action>

内部的处理简略如下

    @Override    public String execute() throws Exception {        ActionContext.getContext().getValueStack().push(exception.getMessage());        return super.execute();    }

3、之所以会出现类似Infinite recursion detected的原因分析

Infinite recursion detected: [//saveClasses!saveClasses, //errorProcessor, //errorProcessor]
的错误,

错误提示非常不明显 -
容易产生误解。

可以理解为Struts2内部会出现这种形式的错误抛出。
这是框架内部的处理。

但是,既然是报错,而且没有正常报出,
考虑到可能是错误处理的冲突问题。

但是测试之后,发现 -
这种简单的配置和处理方式的情况下,内部的异常被捕获之后,
未能正常执行和返回结果集,

而且
Spring对应的exceptionAdvice方法未进入
Struts2对应的ErrorProcessor的方法也未进入执行。

后续测试又发现,
只有Spring的异常处理的时候,相关切面类的方法并未执行。
也就是说,Spring未捕获到错误的抛出。

而程序中断于Struts2内部的堆栈信息提示 -

java.lang.NoSuchMethodException: fjw.struts2.web.interceptor.CostTimeInterceptor.intercept()

证明在Struts2与Spring进行整合的时候,
谁先捕获到错误,会直接完成处理,
程序中断,另一个是不会继续执行了。

但是上述分析到的java.lang.NoSuchMethodException

4、为什么Struts2的自定义方案中未能进行捕获呢?

后续测试,发现,通过上述的配置
Struts2exception拦截器捕获到了异常
java.lang.NoSuchMethodException

然而,程序没有中断,后续陆续的捕获到了
java.lang.ReflectiveOperationException

然后,后续又继续捕获到了
java.lang.NoSuchMethodException
java.lang.ReflectiveOperationException
……

所以说,最后抛出了这样的异常信息 -
Stacktraces
Infinite recursion detected: [//saveClasses!saveClasses, //errorProcessor, //errorProcessor] - [unknown location]

抛出的这个,还是Struts2自身的模板方案,根本没引起自定义异常处理内容的执行。说明Struts2内部,把这种抛出本身作为了一个异常进行了显示。

抛出第一个错误的时候,Struts2内部的程序未中断和返回,而是试图继续捕获后续的错误。
这种情况下,如果是Struts2内部自己处理的话,可以正常抛出相关的内容

Stacktracesjava.lang.NoSuchMethodException: fjw.struts2.web.interceptor.CostTimeInterceptor.intercept()

查看其内部执行代码的流程的话
虽然异常的捕获流程完全相同,
但是,其使用的是模板技术下的界面

Template template = config.getTemplate("/org/apache/struts2/dispatcher/error.ftl");

可以正常显示出错误信息

而上述的简单的异常处理,需要返回到某个视图,但是因为涉及到多个错误。
不使用模板技术,而响应视图的时候,Struts2无法做出正确响应。

在正常的业务流程中,这一类错误是不需要特殊处理的,需要在项目开发过程中,即予以消除

只需要处理自己自定义的特殊错误即可。

多个异常的自定义处理,采用下述代码样式即可。

Below is an example of global and local exception mappings.snippet from struts.xml<struts>    <package name="default">        ...        <global-results>            <result name="login" type="redirect">/Login.action</result>            <result name="Exception">/Exception.jsp</result>        </global-results>        <global-exception-mappings>            <exception-mapping exception="java.sql.SQLException" result="SQLException"/>            <exception-mapping exception="java.lang.Exception" result="Exception"/>        </global-exception-mappings>        ...        <action name="DataAccess" class="com.company.DataAccess">            <exception-mapping exception="com.company.SecurityException" result="login"/>            <result name="SQLException" type="chain">SQLExceptionAction</result>            <result>/DataAccess.jsp</result>        </action>        ...    </package></xwork>

那么,也就不会出现上述问题。

至于,此例为何抛出NoSuchMethodException,请见前文 -
关于 Spring AOP 中,包含参数的成员方法的调用,出现 NoSuchMethodException 的研究
这个,与AOP中的动态代理使用的切入点表达式的自动生成有关系。

5、由此获得结论

在全局异常处理中,异常最好有更强的针对性。
程序运行中的异常,是可提前消除的,不要再去使用全局方案。

如需要转载
请注明文章出处
http://blog.csdn.net/MUXINGYE/article/details/54564328
谢谢~

0 0
原创粉丝点击