`
phpxiaoxin
  • 浏览: 249203 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

cxf spring 发布 webservice 供 .net使用

    博客分类:
  • java
阅读更多

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/

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics