为了能够在项目中正常使用CXF2.x框架提供WebService功能,至少需要以下jar文件:
asm-2.2.3.jar
cglib-nodep-2.1_3.jar
cxf-2.1.2.jar
cxf-manifest.jar
FastInfoset-1.2.2.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-jaxws_2.1_spec-1.0.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.2.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.7.jar
neethi-2.0.4.jar
saaj-api-1.3.jar
wsdl4j-1.6.2.jar
wstx-asl-3.2.4.jar
xml-resolver-1.2.jar
XmlSchema-1.4.2.jar
作者的项目主要应用Spring-2.0.7、hibernate-3.2.5技术框架,在集成CXF时老是抛出以下异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cxfService': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.visit(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
Caused by:
java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.visit(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
at org.apache.cxf.jaxws.WrapperClassGenerator.generatePackageInfo(WrapperClassGenerator.java:227)
at org.apache.cxf.jaxws.WrapperClassGenerator.createWrapperClass(WrapperClassGenerator.java:171)
at org.apache.cxf.jaxws.WrapperClassGenerator.generate(WrapperClassGenerator.java:132)
。。。。。。
在网上查找相关资料,经过反复尝试,终于发现问题的所在。原来
hibernate-3.2.5需要asm-1.x.jar、cglib-2.1.3.jar版本的jar文件,
Spring-2.0.7需要asm-2.2.3.jar,
CXF-2.x需要asm-2.2.3.jar。
这样导致了asm jar文件发生了冲突。为了解决冲突的问题,需要将asm-1.x.jar、cglib-2.1.3.jar版本的jar文件去掉,用Spring提供的cglib-nodep-2.1_3.jar文件替代即可解决此问题。
下面是主要的配置信息:
一、在web.xml文件中的配置
<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/config/applicationContext.xml, /WEB-INF/config/beans-cxf.xml </param-value> </context-param> <servlet> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/cxf/*</url-pattern> </servlet-mapping>
二、java接口
@WebService
public interface CXFService {
public String sayHello(String username);
}
三、接口实现类
@WebService (endpointInterface="com.cjm.webservice.cxf.CXFService")
public class CXFServiceImpl implements CXFService {
public String sayHello(String username) {
if(username==null || username.length()==0){
return "Hello Guest";
}else{
return "Hello " + username;
}
}
}
四、服务端相关bean的配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <bean id="cxfServiceImpl" class="com.cjm.webservice.cxf.CXFServiceImpl"/> <jaxws:endpoint id="cxfService" implementor="#cxfServiceImpl" address="/cxfService" /> </beans>
五、在客户端调用WebService业务方法的范例
1、在spring环境下的调用
生成cxf环境下的接口类的命令:wsdl2java -p com.travelsky.agentsky.ws.client http://localhost:8091/inner/ws/marketInfoWS?wsdl
1)bean的配置
<bean id="client" class="com.cjm.webservice.cxf.CXFService" factory-bean="clientFactory" factory-method="create" /> <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> <property name="serviceClass" value="com.cjm.webservice.cxf.CXFService" /> <property name="address" value="http://localhost:8888/spring2/cxf/cxfService" /> </bean>
2)业务方法调用
CXFService cxf = (CXFService)SpringContextUtil.getBean("client");
String ret = cxf.sayHello("Raymond.Chen");
2、在非spring环境下的调用
//客户端类生成命令:
//wsdl2java -p com.travelsky.monica.ws.client http://localhost:9081/monicaServices/ws/monicaServices?wsdl
List<String> passengerIds = new ArrayList<String>();
passengerIds.add("1n");
passengerIds.add("3n");
List<String> airCodes = new ArrayList<String>();
airCodes.add("cz");
airCodes.add("ca");
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(MonicaServices.class); //服务接口类
factory.setAddress("http://localhost:9081/monicaServices/ws/monicaServices"); //服务地址
System.setProperty("org.apache.cxf.bus.factory", "org.apache.cxf.bus.CXFBusFactory");
MonicaServices client = (MonicaServices) factory.create();
String s = client.generatePnrContent("CAN001", "12345", passengerIds, airCodes, true);