CXF和Spring結合的非常緊密,默認發布Server端是需要用到Spring的,但是項目中用到的Spring jar包比較老2.0,CXF版本2.3.1,跟Spring不兼容,需要換乘Spring2.5,但是換jar包對原來的項目存在風險,上網搜了一個脫 離Spring運行的方法。
寫一個類繼承CXFNonSpringServlet,重寫loadBus方法。
1 @SuppressWarnings("unchecked")
2 public void loadBus(ServletConfig servletConfig) throws ServletException {
3 super.loadBus(servletConfig);
4 Bus bus = this.getBus();
5 BusFactory.setDefaultBus(bus);
6
7 Enumeration<String> enums = getInitParameterNames();
8 while (enums.hasMoreElements()) {
9 String key = enums.nextElement();
10 String value = getInitParameter(key);
11 try {
12 Class clz = Class.forName(value);
13 try {
14 Endpoint.publish(key, clz.newInstance());
15 } catch (InstantiationException e) {
16 e.printStackTrace();
17 } catch (IllegalAccessException e) {
18 e.printStackTrace();
19 }
20 } catch (ClassNotFoundException e) {
21 e.printStackTrace();
22 }
23 }
24 }
2 public void loadBus(ServletConfig servletConfig) throws ServletException {
3 super.loadBus(servletConfig);
4 Bus bus = this.getBus();
5 BusFactory.setDefaultBus(bus);
6
7 Enumeration<String> enums = getInitParameterNames();
8 while (enums.hasMoreElements()) {
9 String key = enums.nextElement();
10 String value = getInitParameter(key);
11 try {
12 Class clz = Class.forName(value);
13 try {
14 Endpoint.publish(key, clz.newInstance());
15 } catch (InstantiationException e) {
16 e.printStackTrace();
17 } catch (IllegalAccessException e) {
18 e.printStackTrace();
19 }
20 } catch (ClassNotFoundException e) {
21 e.printStackTrace();
22 }
23 }
24 }
在web.xml里將要發布的類配置一下,可以配置多個
1 <servlet>
2 <servlet-name>CXFServlet</servlet-name>
3 <servlet-class>
4 com.infodms.ws.util.MyCXFNoSpringServlet
5 </servlet-class>
6 <init-param>
7 <param-name>/TestService</param-name>
8 <param-value>com.infodms.ws.test.TestServiceImpl</param-value>
9 </init-param>
10 <init-param>
11 <param-name>/HelloWorld</param-name>
12 <param-value>com.infodms.ws.test.HelloWorldImpl</param-value>
13 </init-param>
14 </servlet>
15 <servlet-mapping>
16 <servlet-name>CXFServlet</servlet-name>
17 <url-pattern>/ws/*</url-pattern>
18 </servlet-mapping>
2 <servlet-name>CXFServlet</servlet-name>
3 <servlet-class>
4 com.infodms.ws.util.MyCXFNoSpringServlet
5 </servlet-class>
6 <init-param>
7 <param-name>/TestService</param-name>
8 <param-value>com.infodms.ws.test.TestServiceImpl</param-value>
9 </init-param>
10 <init-param>
11 <param-name>/HelloWorld</param-name>
12 <param-value>com.infodms.ws.test.HelloWorldImpl</param-value>
13 </init-param>
14 </servlet>
15 <servlet-mapping>
16 <servlet-name>CXFServlet</servlet-name>
17 <url-pattern>/ws/*</url-pattern>
18 </servlet-mapping>
配置完成,啟動tomcat,報錯,還是加載了spring,但是代碼確實走了剛剛加的MyCXFNoSpringServlet
1 java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.cxf.bus.spring.BusApplicationListener' defined in class path resource [META-INF/cxf/cxf.xml]: Initialization of bean failed; nested exception is java.lang.NoSuchMethodError: org.springframework.context.support.AbstractApplicationContext.addApplicationListener(Lorg/springframework/context/ApplicationListener;)V
2 org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:96)
2 org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:96)
調試了一下源碼,內部需要從環境變量中取得org.apache.cxf.bus.factory的值,如果為空就默認按照spring的方式加載。于是在類的最開始加入一行代碼
1 System.setProperty("org.apache.cxf.bus.factory", "org.apache.cxf.bus.CXFBusFactory");
再次啟動tomcat,報錯,由異常可知WoodstoxValidationImpl類沒有默認構造方法,通過反射實例化對象報錯,看了一下這個類的源碼,確實沒有無參構造方法
1 Caused by: java.lang.InstantiationException: org.apache.cxf.wstx_msv_validation.WoodstoxValidationImpl
2 at java.lang.Class.newInstance0(Class.java:340)
3 at java.lang.Class.newInstance(Class.java:308)
4 at org.apache.cxf.bus.extension.Extension.load(Extension.java:110)
2 at java.lang.Class.newInstance0(Class.java:340)
3 at java.lang.Class.newInstance(Class.java:308)
4 at org.apache.cxf.bus.extension.Extension.load(Extension.java:110)
引用這個,加入三個jar包
woodstox-core-asl-4.0.8.jar
stax2-api-3.0.2.jar
msv.jar
問題解決。
http://liuqiang5151.iteye.com/blog/840496