利用CXF的wsdl2java来建立Web Service. (转载)

来源:互联网 发布:js test方法 编辑:程序博客网 时间:2024/06/05 20:14

刚开始接触的是Xfire,由于xfire几年没有维护了,兼容性不是很好,同时会自动在wsdl中产生一些垃圾的东西,特别是如果类中的字段用到了xfire字的泛型,则wsdl非常的庞大,并且客户端根据wsdl生成的代码也特别多.本来只要定义好了wsdl,就只需要把这个wsdl文档给用户生成客户端的,但是由于xfire的不兼容性,经常需要把xfire的web service运行后的wsdl拷贝出来给用户.

所以,今天决定放弃xfire了,改用CFX。由于cfx是Apache的一个开源项目,在兼容性方面那是不比说的了。首先定义好一个wsdl文档,定义的时候就没有必要像在xfire那种考虑元素的类型、约束等。同一个wsdl文档用xfire生成服务端,再用别的工具如wsdl.exe生成客户端,如果没有好好的约束和设计好,客户端直接调用服务端是不行的,今天发现xfire的一个特点就是对于xsd的命名空间如果会自定更改为java中类的包路径,比如wsdl文档时这样的:

<xsd:schema targetNamespace="http://services.sxit.com/cueapinterfaceforsi/">

则web 服务运行后的wsdl是:

<xsd:schema targetNamespace="http://cueapinterfaceforsi.services.sxit.com"/>.

这样就不能直接用原wsdl文件生成客户端与web服务交互了.当然,有的人会可以利用aegis.xml来映射,不过我没有用过,不知道行不行。但是在cfx下就不需要考虑这些问题了,直接定义好wsdl文档,利用别的工具生成的客户端都能正常访问web 服务。

定义好了一个wsdl文档后,就可以利用cfx的wsdl2server工具来生成类接口和接口实现类,有的程序员做web服务的时候喜欢直接写接口、类以及相关的数据类,再创建web server。其实这样有点麻烦,光写代码就要写好久,有时还要注意什么命名空间、element的名称啊,如果事先写好了wsdl的话,直接利用工具生成服务端,那岂不是省了很多代码量 ,闲话少说,还是回去主题吧。

首先在Apache网站上下载cfx包,解压缩到某路径,然后设置环境变量:

CXF_HOME=e:/java/apache-cxf-2.1.3,以及在path中增加 % CXF_HOME%/bin。然后就可以在控制台上输入:

wsdl2java -impl -server CueapInterfaceForSI.wsdl来生成接口类、实现类和其他的数据类了。-impl参数是要求生成实现类,如果没有这个参数,则仅仅生成接口和其他元素类。

然后搭建cfx环境,在MyEclipse中新建一个Web Server Project.类型选择JAX-WS.项目创建成功后,把cfx文件夹中lib目录下所有的jar文件拷贝到工程的lib目下中。然后把利用wsdl2java工具生成的java代码拷贝到工程的src目录下.然后需要修改一个地方,就是在接口的实现类中把wsdlLocation = "file:CueapInterfaceForSI.wsdl"这个东东给删除,不然等会运行是会提示找不到这个wsdl文件.在web-inf目录下新建一个beans.xml文件,内容如下:
<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.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" />

<jaxws:endpoint
id="CueapInterfaceForSI"
implementor="com.sxit.services.cueapinterfaceforsi.CueapInterfaceForSIImpl"
address="/CueapInterfaceForSI" />

</beans>



然后配置web.xml:

<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/beans.xml</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>



运行tomcat,在url中输入http://127.0.0.1:8080/bnetinterface/services/CueapInterfaceForSI?wsdl.查看到的wsdl内容就跟源wsdl文档的一样了,不用像在xfire下担心不一致了,也没有xfire那么复杂和庞大。



利用.NET的wsdl工具根据源wsdl文档生成客户端,新建一个测试类,创建一个测试数据,就能直接调用服务端了。传送的数据和返回的数据都一致,再也不用担心参数值为null了。

原创粉丝点击