cxf 是 xfire 的替代工具。用来发布webservice。官方网站:http://cxf.apache.org/ 关于使用可以参考:
官方:http://cxf.apache.org/docs/writing-a-service-with-spring.html
或者: 使用CXF实现webservice发 布+spring
或者:XFire的下一代产品CXF的入门(二) - 与Spring的集成
文章里使用了不少注解,其实只需要两个甚至一个就足够了。
需要注意的有以下几点问题:
1.需要引入jar包为:cxf-2.3.1.jar neethi-2.0.4.jar wsdl4j-1.6.2.jar XmlSchema-1.4.7.jar xpp3_min-1.1.4c.jar
可能还会以来其他的,大家根据情况自己引入。
2.写好了接口和实现,以及方法后,只需要加一个@WebService的接口将接口和实现关联我的如下:
@WebService(endpointInterface = "com.phpxiaoxinl.remote.service.HotelReservationService")
@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING)
public class HotelReservationServiceImpl implements HotelReservationService {
@Override
public SearchHotelRS searchHotel(SearchHotelRQ searchHotelRequest) {
//impl
return null;
}
}
这里用到了@BindingType的注解,将wsdl发布成soap1.2协议(还有soap1.1)。而1.2与1.1的区别可以通过wsdl看出来:其中1.2会有:
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" 或者 xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
而如果去掉这个注解其协议将默认为1.1.
还有一个问题,你会发现我使用的是searchHotelRQ,searchHotelRS ,而不是 searchHotelRequest,searchHotelReponse 原因是我没有加注解,而cxf生成wsdl的时候有命名空间会自动加request或者是reponse,这样方法名和输入输出很可能造成相同的命名空间(因为这个我调试到半夜2点...),所以大家最好不要将输入和输出带上request或者reponse,否则就最好将searchHotel的方法名改成其他的。
3.数据绑定问题。
.net调用时候,vs可以自动生成对象,但是默认会生成一个字段名+Specified的字段,原因细节参考:
http://it.chinawin.net/softwaredev/article-13328.html
这个问题我不十分清楚其原因,估计是因为数据转换的问题。这个可以通过aegis来解决。具体配置参考如下:
<?xml version="1.0" encoding="UTF-8"?> <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="hotelB2CReservationService" class="com.phpxiaoxin.service.HotelReservationServiceImpl"> <property name="bookingHotelService" ref="bookingHotelService"/> </bean> <jaxws:endpoint id="hotelReservation" implementor="#hotelReservationService" address="/hotelReservation"> <jaxws:serviceFactory> <ref bean='jaxws-and-aegis-service-factory' /> </jaxws:serviceFactory> </jaxws:endpoint> <bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding" scope="prototype"/> <bean id="jaxws-and-aegis-service-factory" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean" scope="prototype"> <property name="dataBinding" ref="aegisBean"/> </bean> </beans>
也可参考cxf官方的文档:
http://cxf.apache.org/docs/aegis-databinding-20x.html
这样生成的wsdl就会由:
<xs:element minOccurs="0" name="branchId" type="xs:long"></xs:element>
成为:
<xsd:element minOccurs="0" name="branchId" nillable="true" type="xsd:long"></xsd:element>
切换之后我遇到的第一个问题就是:
java.lang.UnsupportedOperationException: This parser does not support specification "null" version "null"
查了一下是因为jar包的原因。 解析xml的jar:xercesImpl-2.9.1.jar 要用2.9.1以上的。可以参考:
https://jira.kuali.org/browse/KULRICE-2810
第二个是.net调用的时候报错:
原因是.net调用的时候设置了压缩xml的参数:DecompressionEnabled = true
参考:HttpTransportBindingElement. DecompressionEnabled
就这些吧。
另外我遇到的问题就是,由于我使用了weblogic作为服务器,而.net调用的时候出现如下错误:
Unsupported encoding: "utf-8; action=""" specified.
java.io.UnsupportedEncodingException: Unsupported Encoding utf-8; action=""
at weblogic.servlet.internal.ServletRequestImpl.setCharacterEncoding(ServletRequestImpl.java:428)
错误原因是因为.net使用了soap1.2协议,生成的header为:
Headers: {content-type=[application/soap+xml; charset=utf-8; action=""]
而soap1.1则生成如下的header:
Headers: {content-type=[text/xml; charset=UTF-8], SOAPAction=[""]
weblogic解析的时候出了bug,没有将utf-8后面的内容截掉,导致这个错误。所以可以设置成soap1.1来调用。具体.net的设置可以在文档中查找soap,找到相关的配置,设置到配置文件中,也可以参考下面的地址
参考:http://www.coderanch.com/t/224524/Web-Services/java/SOAPAction-header
如果是cxf来调用其他人提供的webservice,在已经有wsdl的情况下,可以参考这个文章来完成:
http://blogold.chinaunix.net/u2/73798/showart_2002108.html
主要就是通过cxf提供的工具,通过命令行来生成java对象:
wsdl2java -d src -client http://localhost:8080/webservice/hotelB?wsdl
这篇文章也不错:
http://enna.blog.163.com/blog/static/2058701120093242346371/