我在网上看到一个spring 结合webwork的实例,自己弄了一下,发现老出现一个奇怪的错误
按照下面的配置,会出现一个一样的错误
?
严重: Could not execute action
java.lang.IllegalStateException: The application context has not been set on this resolver
?at com.opensymphony.xwork.spring.SpringExternalReferenceResolver.resolveReferences(SpringExternalReferenceResolver.java:38)
?at com.opensymphony.xwork.interceptor.ExternalReferencesInterceptor.before(ExternalReferencesInterceptor.java:40)
?at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:34)
?at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)
?at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)
?at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)
?at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)
?at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)
?at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)
?at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)
?at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)
?at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)
?at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)
?at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)
?at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)
?at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)
?at com.opensymphony.xwork.DefaultActionProxy.execute(DefaultActionProxy.java:115)
?at com.opensymphony.webwork.dispatcher.ServletDispatcher.serviceAction(ServletDispatcher.java:229)
?at com.opensymphony.webwork.dispatcher.ServletDispatcher.service(ServletDispatcher.java:199)
?at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
?at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
?at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
?at org.springframework.orm.hibernate.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)
?at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
?at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
?at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
?at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
?at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
?at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
?at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
?at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
?at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
?at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:873)
?at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
?at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
?at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
?at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
?at java.lang.Thread.run(Unknown Source)
?
我使用的是spring-xwork-integration.jar 这jar包来在webwork的action里面IOC注入spring的bean对象,异常提示的代码:?The application context has not been set on this resolver 经分析就是在spring-xwork-integration.jar 的SpringExternalReferenceResolver里,其中一段代码如下
?
? public void resolveReferences(ActionInvocation paramActionInvocation)
??? throws ReferenceResolverException
? {
??? if(this.applicationContext == null) throw new IllegalStateException("The application context has not been set on this resolver");
?
?
--------------------
?
}
也就是说方法里的applicationContext?取不到,真奇怪,我在web.xml里配置了该jar包的listener
?
?<listener>
??<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
?</listener>???
?
?
? <listener>
?? <listener-class>com.opensymphony.xwork.spring.SpringObjectFactoryListener</listener-class>
? </listener> ?-----------------这个就是spring-xwork-integration.jar里的listener
?
代码里主要片段:
?
? public void contextInitialized(ServletContextEvent paramServletContextEvent)
? {
??? ServletContext localServletContext = paramServletContextEvent.getServletContext();
??? WebApplicationContext localWebApplicationContext = WebApplicationContextUtils.getWebApplicationContext(localServletContext);
??? SpringObjectFactory localSpringObjectFactory = new SpringObjectFactory();
??? localSpringObjectFactory.setApplicationContext(localWebApplicationContext);
??? ObjectFactory.setObjectFactory(localSpringObjectFactory);
? }
?
?里面是可以得到applicationContext?对象的,但是手工装配的SpringExternalReferenceResolver里没有给applicationContext?赋值,所以报错了,所以我更改了jar里的类,我首先用jd-gui.exe反编译jar,把这3个文件修改了
主要是在SpringObjectFactoryListener里新增一个静态实例变量
?
public static org.springframework.context.ApplicationContext.ApplicationContext aplicationContextWeb = null;
?
然后再contextInitialized方法体里赋值
aplicationContextWeb = localWebApplicationContext;
?
那么在SpringExternalReferenceResolver里,在使用applicationContext前赋值
?
?
applicationContext = SpringObjectFactoryListener.aplicationContextWeb;
?
编译好后,打jar包,覆盖原来的,重启tomcat,就通过了手工装配的测试。
?
但是如果在web.xml里把
?
?<listener>
??<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
?</listener>???
?
?
? <listener>
?? <listener-class>com.opensymphony.xwork.spring.SpringObjectFactoryListener</listener-class>
? </listener> ?-----------------这个就是spring-xwork-integration.jar里的listener
?
2个位置对调,变成
?
? <listener>
?? <listener-class>com.opensymphony.xwork.spring.SpringObjectFactoryListener</listener-class>
? </listener> ?-----------------这个就是spring-xwork-integration.jar里的listener
?
?<listener>
??<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
?</listener>???
?
系统又会出错,这个问题更复杂,具体原因我还不是是否清楚。有哪位精通的高手给我答案吗???????????
?
--------------这个问题我现在分析了spring-xwork-integration.jar里的java文件,发现原来jar里需要把ServletContextEvent 通过spring提供的WebApplicationContextUtils.getWebApplicationContext()来转换
成spring自己的ApplicationContext,所以说,必须选侦听spring的ContextLoaderListener,在侦听SpringObjectFactoryListener,位置不能反,否则会报错。
?
?
谢谢啦!!!!!!!!!!!!!!!!!!
?
附近里的第一个jar文件是我修改过的!!!!!!!!!!!!!!(这后来发现是垃圾,可能被删除过文件的)
第二个jar包是比较完整的,是正确的
2010-5-26 18:19 我此时才发现,我在公司使用的spring-xwork-integration.jar 有重大问题,大小才8k不到,靠,郁闷啊,好像不对的,真正的spring-xwork-integration.jar应该比这个大,而且里面不止3个class,估计问题出在这里(当然也不排除jar的版本问题,但是我不知道怎么看版本,也许第二个jar包的版本比较新吧,只能猜测。),上面的错误也跟这个jar包有关,新的jar换上去,问题就解决了,哈哈。垃圾啊,被人陷害了。怪不得网上找这问题,答案非常少啦,原来是这么回事。
------------------------------------------------下面是我看到的例子 原文在http://gis8.blog.sohu.com/41790075.html?----------------------------------------
?一个手动装配的Spring与Webwork集成配置示例
在web.xml中配置如下内容:
?<listener>
??<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
?</listener>
?<!--有人说这句话要放上,可我发现如果在Webwork2.2.4的webwork.properties配置文件中配置了webwork.objectFactory = spring,则可以去掉,实践出真知哟:-)-->
?<!--listener>
??<listener-class>com.opensymphony.xwork.spring.SpringObjectFactoryListener</listener-class>
?</listener-->?
--------------这个侦听器好像是旧版本的,比较新的版本已经改为SpringExternalReferenceResolverSetupListener了,看不到这个SpringObjectFactoryListener了
xwork.xml文件,如下:
1 <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"
2 "http://www.opensymphony.com/xwork/xwork-1.0.dtd">
3 <xwork>
4?<include file="webwork-default.xml"/>
5?<!--?注意是com.opensymphony.xwork.spring.SpringExternalReferenceResolver -->
6?<package name="myDefault" extends="webwork-default"?
7??externalReferenceResolver="com.opensymphony.xwork.spring.SpringExternalReferenceResolver">
8??<interceptors> <!-- 定义一组拦截器 -->
9???? <interceptor name="myReferenceResolver" <!--不使用自动装配时,使用ExternalReferencesInterceptor-->
10?????????? class="com.opensymphony.xwork.interceptor.ExternalReferencesInterceptor"/>
11??? <interceptor-stack name="myDefaultStack">
12????? <interceptor-ref name="defaultStack"/>
13?????? <interceptor-ref name="params"/>
14?????? <interceptor-ref name="myReferenceResolver" />
15????? </interceptor-stack>
16??? </interceptors>
17?? <default-interceptor-ref name="myDefaultStack"/> <!-- 名称与第11行相同,指定默认的拦截器-->
18? </package>
19 </xwork>
自定义的Action配置文件,样式如下:
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"><xwork>
?<package name="demo" extends="myDefault" >
??<action name="demo" class="com.demo.DemoAction">
???<external-ref name="demoLogic">myLogic</external-ref><!-- 这时外部引用Bean名称与Action属性名称可以不相同,使用ActionAutowiringInterceptor时很难做到这一点-->
???<result name="success">test.jsp</result>
??</action>
?</package>
</xwork>