问题描述
手动装配Spring与Webwork配置修改spring-xwork-integration.jar方法实现永久链接:http://panshunchang.javaeye.com/blog/675464我在网上看到一个spring结合webwork的实例,自己弄了一下,发现老出现一个奇怪的错误按照下面的配置,会出现一个一样的错误严重:Couldnotexecuteactionjava.lang.IllegalStateException:Theapplicationcontexthasnotbeensetonthisresolveratcom.opensymphony.xwork.spring.SpringExternalReferenceResolver.resolveReferences(SpringExternalReferenceResolver.java:38)atcom.opensymphony.xwork.interceptor.ExternalReferencesInterceptor.before(ExternalReferencesInterceptor.java:40)atcom.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:34)atcom.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)atcom.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)atcom.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)atcom.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)atcom.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)atcom.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)atcom.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)atcom.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)atcom.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)atcom.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)atcom.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)atcom.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35)atcom.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165)atcom.opensymphony.xwork.DefaultActionProxy.execute(DefaultActionProxy.java:115)atcom.opensymphony.webwork.dispatcher.ServletDispatcher.serviceAction(ServletDispatcher.java:229)atcom.opensymphony.webwork.dispatcher.ServletDispatcher.service(ServletDispatcher.java:199)atjavax.servlet.http.HttpServlet.service(HttpServlet.java:729)atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)atorg.springframework.orm.hibernate.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)atorg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)atorg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)atorg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)atorg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)atorg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)atorg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)atorg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)atorg.apache.coyote.http11.Http11Processor.process(Http11Processor.java:873)atorg.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)atorg.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)atorg.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)atorg.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)atjava.lang.Thread.run(UnknownSource)我使用的是spring-xwork-integration.jar这jar包来在webwork的action里面IOC注入spring的bean对象,异常提示的代码:Theapplicationcontexthasnotbeensetonthisresolver经分析就是在spring-xwork-integration.jar的SpringExternalReferenceResolver里,其中一段代码如下publicvoidresolveReferences(ActionInvocationparamActionInvocation)throwsReferenceResolverException{if(this.applicationContext==null)thrownewIllegalStateException("Theapplicationcontexthasnotbeensetonthisresolver");--------------------}也就是说方法里的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里的listenerSpringObjectFactoryListener代码里主要片段:publicvoidcontextInitialized(ServletContextEventparamServletContextEvent){ServletContextlocalServletContext=paramServletContextEvent.getServletContext();WebApplicationContextlocalWebApplicationContext=WebApplicationContextUtils.getWebApplicationContext(localServletContext);SpringObjectFactorylocalSpringObjectFactory=newSpringObjectFactory();localSpringObjectFactory.setApplicationContext(localWebApplicationContext);ObjectFactory.setObjectFactory(localSpringObjectFactory);}里面是可以得到applicationContext对象的,但是手工装配的SpringExternalReferenceResolver里没有给applicationContext赋值,所以报错了,所以我更改了jar里的类,我首先用jd-gui.exe反编译jar,把这3个文件修改了主要是在SpringObjectFactoryListener里新增一个静态实例变量publicstaticorg.springframework.context.ApplicationContext.ApplicationContextaplicationContextWeb=null;然后到SpringExternalReferenceResolver这个java类里的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里的listener2个位置对调,变成<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>系统又会出错,这个问题更复杂,具体原因我还不是是否清楚。有哪位精通的高手给我答案吗???????????谢谢啦!!!!!!!!!!!!!!!!!!javaeyes里我也发表了,里面可以传文件------------------------------------------------下面是我看到的例子原文在http://gis8.blog.sohu.com/41790075.html----------------------------------------------------------------------------一个手动装配的Spring与Webwork集成配置示例标签:webworkspring集成配置手动装配在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.SpringExternalReferenceResolver</listener-class></listener-->xwork.xml文件,如下:1<!DOCTYPExworkPUBLIC"-//OpenSymphonyGroup//XWork1.0//EN"2"http://www.opensymphony.com/xwork/xwork-1.0.dtd">3<xwork>4<includefile="webwork-default.xml"/>5<!--注意是com.opensymphony.xwork.spring.SpringExternalReferenceResolver-->6<packagename="myDefault"extends="webwork-default"7externalReferenceResolver="com.opensymphony.xwork.spring.SpringExternalReferenceResolver">8<interceptors><!--定义一组拦截器-->9<interceptorname="myReferenceResolver"<!--不使用自动装配时,使用ExternalReferencesInterceptor-->10class="com.opensymphony.xwork.interceptor.ExternalReferencesInterceptor"/>11<interceptor-stackname="myDefaultStack">12<interceptor-refname="defaultStack"/>13<interceptor-refname="params"/>14<interceptor-refname="myReferenceResolver"/>15</interceptor-stack>16</interceptors>17<default-interceptor-refname="myDefaultStack"/><!--名称与第11行相同,指定默认的拦截器-->18</package>19</xwork>自定义的Action配置文件,样式如下:<!DOCTYPExworkPUBLIC"-//OpenSymphonyGroup//XWork1.0//EN""http://www.opensymphony.com/xwork/xwork-1.0.dtd"><xwork><packagename="demo"extends="myDefault"><actionname="demo"class="com.demo.DemoAction"><external-refname="demoLogic">myLogic</external-ref><!--这时外部引用Bean名称与Action属性名称可以不相同,使用ActionAutowiringInterceptor时很难做到这一点--><resultname="success">test.jsp</result></action></package></xwork>
解决方案
解决方案二:
这是由于我用的spring-xwork-integration.jar有问题,而且class类也只有3个,版本有问题,重新下载一份spring-xwork-integration.jar就可以看到,跟你原来的不一样了,而且你侦听的listener也应该为:<listener-class>org.springframework.web.context.SpringExternalReferenceResolverSetupListener</listener-class>而非<listener-class>org.springframework.web.context.SpringObjectFactoryListener</listener-class>这样就可以了!而且如果要自动装配(也就是xwork里不需要配置external-ref),那么方法有:建立一个拦截器,加到默认的拦截器中,拦截器使用下面方法注入bean到action((AbstractApplicationContext)applicationContext).getBeanFactory().autowireBeanProperties(invocation.getAction(),AutowireCapableBeanFactory.AUTOWIRE_BY_NAME,false);即可
解决方案三:
解决了!学了一些东西!