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

##关于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内部自己处理的话,可以正常抛出相关的内容

Stacktraces

java.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、由此获得结论

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

如需要转载 请注明文章出处 **https://my.oschina.net/u/3032872/blog/1648372 ** 谢谢~

转载于:https://my.oschina.net/u/3032872/blog/1648372

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值