XFire构建web services客户端的五种方式
本文主要源于先前看到的一篇文章,为了自己以后查看方便也就转载过来了
原文链接:http://blog.csdn.net/jadyer/article/details/6082948
另外还有第四种,第五种方法,是从别处看到的 ,在本文最后和大家分享一下
?
这里并未涉及到JSR?181?Annotations?的相关应用,具体的三种方式如下
①?通过WSDL地址来创建动态客户端?
②?通过服务端提供的接口来创建客户端?
③?使用Ant通过WSDL文件来生成客户端
第一种方式:通过WSDL地址来创建动态客户端
view plainprint?- package?com.jadyer.client;??
- import?java.net.MalformedURLException;??
- import?java.net.URL;??
- import?org.codehaus.xfire.client.Client;??
- /**?
- ?*?通过WSDL来创建动态客户端?
- ?*?@see?此时需要在项目中引入XFire?1.2?Core?Libraries和XFire?1.2?HTTP?Client?Libraries?
- ?*/??
- public?class?ClientFromWSDL?{??
- ????public?static?void?main(String[]?args)?throws?MalformedURLException,?Exception?{??
- ????????Client?client?=?new?Client(new?URL("http://127.0.0.1:8080/XFire_demo/services/XFireServer?wsdl"));??
- ????????Object[]?results11?=?client.invoke("sayHello",?new?Object[]{"Jadyer22"});??
- ????????System.out.println(results11[0]);??
- ????}??
- }??
?
?
第二种方式:通过服务端提供的端口来创建客户端
view plainprint?- package?com.jadyer.client;??
- import?java.net.MalformedURLException;??
- import?java.util.List;??
- import?org.codehaus.xfire.client.XFireProxyFactory;??
- import?org.codehaus.xfire.service.Service;??
- import?org.codehaus.xfire.service.binding.ObjectServiceFactory;??
- import?com.jadyer.model.Person;??
- import?com.jadyer.model.User;??
- import?com.jadyer.server.HelloService;??
- /**?
- ?*?通过Web服务端提供的接口来创建客户端?
- ?*?@see?客户端必须提供一个与服务端完全一致的接口,包名也要一致?
- ?*?@see?在本例中,需要在客户端(即该项目)中提供HelloService.java接口,以及Person和User两个POJO类?
- ?*?@see?并且此时需要在项目中引入XFire?1.2?Core?Libraries和XFire?1.2?HTTP?Client?Libraries?
- ?*/??
- public?class?ClientFromInterface?{??
- ????public?static?void?main(String[]?args)throws?MalformedURLException{??
- ????????//首先使用XFire的ObjectServiceFactory从HelloService接口创建一个服务模型serviceModel??
- ????????//serviceModel包含服务的说明,换句话说,就是服务的元数据??
- ????????//Create?a?metadata?of?the?service??
- ????????Service?serviceModel?=?new?ObjectServiceFactory().create(HelloService.class);??
- ??????????
- ????????//访问的地址??
- ????????String?serviceURL?=?"http://127.0.0.1:8080/XFire_demo/services/XFireServer";??
- ??????????
- ????????//通过查看org.codehaus.xfire.client.XFireProxyFactory源码发现??
- ????????//下面两行代码与这里直接new?XFireProxyFactory()的作用是等效的??
- ????????//XFire?xfire?=?XFireFactory.newInstance().getXFire();??
- ????????//XFireProxyFactory?factory?=?new?XFireProxyFactory(xfire);??
- ????????//为XFire获得一个代理工厂对象??
- ????????//Create?a?proxy?for?the?deployed?service??
- ????????XFireProxyFactory?factory?=?new?XFireProxyFactory();??
- ??????????
- ????????//通过proxyFactory,使用服务模型serviceModel和服务端点URL(用来获得WSDL)??
- ????????//得到一个服务的本地代理,这个代理就是实际的客户端??
- ????????HelloService?client?=?(HelloService)factory.create(serviceModel,?serviceURL);??
- ??????????
- ????????/**?
- ?????????*?Invoke?the?service?
- ?????????*?@see?调用服务的本地代理(即实际的客户端)中的方法,便得到我们需要的WebServcie?
- ?????????*/??
- ??????????
- ????????/*--处理简单对象--*/??
- ????????String?serviceResponse?=?client.sayHello("Jadyer11");??
- ????????System.out.println(serviceResponse);??
- ??????????
- ????????/*--处理对象--*/??
- ????????User?u?=?new?User();??
- ????????u.setName("Jadyer99");??
- ????????Person?pp?=?client.getPerson(u);??
- ????????System.out.println(pp.getName());??
- ??????????
- ????????/*--处理List--*/??
- ????????List<Person>?personList?=?client.getPersonList(24,?"Jadyer88");??
- ????????for(Person?p?:?personList){??
- ????????????System.out.println(p.getName());??
- ????????}??
- ????}??
- }??
?
这是它要用到的接口和两个POJO类
view plainprint?- /**?
- ?*?Web服务提供给客户端的接口?
- ?*?@see?这是第二种方式创建的客户端,要用到的接口?
- ?*/??
- package?com.jadyer.server;??
- import?java.util.List;??
- import?com.jadyer.model.Person;??
- import?com.jadyer.model.User;??
- public?interface?HelloService?{??
- ????public?String?sayHello(String?name);??
- ????public?Person?getPerson(User?u);??
- ????public?List<Person>?getPersonList(Integer?age,?String?name);??
- }??
- /**?
- ?*?第二种方式创建的客户端,要用到的两个POJO类?
- ?*/??
- package?com.jadyer.model;??
- public?class?User?{??
- ????private?String?name;??
- ????/*--getter和setter略--*/??
- }??
- package?com.jadyer.model;??
- public?class?Person?{??
- ????private?Integer?age;??
- ????private?String?name;??
- ????/*--getter和setter略--*/??
- }??
?
第三种方式:使用Ant通过WSDL文件来生成客户端
view plainprint?- package?com.jadyer.client;??
- /**?
- ?*?使用Ant通过WSDL生成客户端?
- ?*?@see?这里的ClientFromAnt.java是我自己创建的,并非Ant生成?
- ?*?@see?这里要用到的JAR有:xfire-all-1.2.6.jar以及//xfire-distribution-1.2.6//lib//目录中的所有JAR包?
- ?*?@see?我们需要把这些JAR包都拷贝到Web?Project//WebRoot//WEB-INF//lib//目录中?
- ?*?@see?然后把build.xml和MyFirstXFireServer.wsdl都拷贝到下Web?Project的根目录下即可?
- ?*?@see?关于MyFirstXFireServer.wsdl文件,是我在WebServices服务启动后?
- ?*?@see?访问http://127.0.0.1:8080/XFire_demo/services/XFireServer?wsdl然后将其另存得到的?
- ?*/??
- public?class?ClientFromAnt?{??
- ????public?static?void?main(String[]?args)?{??
- ????????XFireServerClient?client?=?new?XFireServerClient();??
- ????????//String?url?=?"http://127.0.0.1:8080/XFire_demo/services/XFireServer";??
- ????????//String?result?=?client.getXFireServerHttpPort(url).sayHello("Jadyer33");??
- ????????//上面的两行代码,与下面的这一行代码,同效~~??
- ????????String?result?=?client.getXFireServerHttpPort().sayHello("Jadyer33");??
- ??????????
- ????????System.out.println(result);??
- ????}??
- }??
?
用到的Ant文件,如下
view plainprint?- <?xml?version="1.0"?encoding="UTF-8"?>??
- <project?name="wsgen"?default="wsgen"?basedir=".">??
- ????<path?id="classpathId">??
- ????????<fileset?dir="./WebRoot/WEB-INF/lib">??
- ????????????<include?name="*.jar"?/>??
- ????????</fileset>??
- ????</path>??
- ??????
- ????<taskdef?classpathref="classpathId"?name="wsgen"?classname="org.codehaus.xfire.gen.WsGenTask"/>??
- ??????
- ????<target?name="wsgen"?description="generate?client">??
- ????????<wsgen?outputDirectory="./src/"?wsdl="MyFirstXFireServer.wsdl"?binding="xmlbeans"?package="com.jadyer.client"?overwrite="true"/>??
- ????</target>??
- </project>??
?
也可以使用下面的这个Ant文件
view plainprint?- <?xml?version="1.0"?encoding="UTF-8"?>??
- <project?name="xfireAnt"?basedir="."?default="createClientCode">??
- ????<property?name="xfirelib"?value="${basedir}/WebRoot/WEB-INF/lib"/>??
- ????<property?name="sources"?value="${basedir}/src"/>??
- ????<path?id="classpath">??
- ????????<fileset?dir="${xfirelib}">??
- ????????????<include?name="*.jar"/>??
- ????????</fileset>??
- ????</path>??
- ??????????
- ????<target?name="createClientCode">??
- ????????<taskdef?name="wsgen"?classname="org.codehaus.xfire.gen.WsGenTask"?classpathref="classpath"/>??
- ????????<wsgen?outputDirectory="${sources}"?wsdl="http://127.0.0.1:8080/XFire_demo/services/XFireServer?wsdl"?package="com.jadyer.client"?overwrite="true"/>??
- ????</target>??
- </project>??
?
最后我再把MyFirstXFireServer.wsdl的内容,附加上
view plainprint?- <?xml?version="1.0"?encoding="UTF-8"?>??
- <wsdl:definitions?targetNamespace="http://www.jadyer.com/XFireDemo"??
- ????xmlns:tns="http://www.jadyer.com/XFireDemo"??
- ????xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"??
- ????xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"??
- ????xmlns:xsd="http://www.w3.org/2001/XMLSchema"??
- ????xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/"??
- ????xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding"??
- ????xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/"??
- ????xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">??
- ????<wsdl:types>??
- ????????<xsd:schema?xmlns:xsd="http://www.w3.org/2001/XMLSchema"??
- ????????????????????attributeFormDefault="qualified"??
- ????????????????????elementFormDefault="qualified"??
- ????????????????????targetNamespace="http://www.jadyer.com/XFireDemo">??
- ????????????<xsd:element?name="sayHello">??
- ????????????????<xsd:complexType>??
- ????????????????????<xsd:sequence>??
- ????????????????????????<xsd:element?maxOccurs="1"?minOccurs="1"?name="in0"?nillable="true"?type="xsd:string"?/>??
- ????????????????????</xsd:sequence>??
- ????????????????</xsd:complexType>??
- ????????????</xsd:element>??
- ????????????<xsd:element?name="sayHelloResponse">??
- ????????????????<xsd:complexType>??
- ????????????????????<xsd:sequence>??
- ????????????????????????<xsd:element?maxOccurs="1"?minOccurs="1"?name="out"?nillable="true"?type="xsd:string"?/>??
- ????????????????????</xsd:sequence>??
- ????????????????</xsd:complexType>??
- ????????????</xsd:element>??
- ????????</xsd:schema>??
- ????</wsdl:types>??
- ????<wsdl:message?name="sayHelloRequest">??
- ????????<wsdl:part?name="parameters"?element="tns:sayHello"></wsdl:part>??
- ????</wsdl:message>??
- ????<wsdl:message?name="sayHelloResponse">??
- ????????<wsdl:part?name="parameters"?element="tns:sayHelloResponse"></wsdl:part>??
- ????</wsdl:message>??
- ????<wsdl:portType?name="XFireServerPortType">??
- ????????<wsdl:operation?name="sayHello">??
- ????????????<wsdl:input?name="sayHelloRequest"?message="tns:sayHelloRequest">??
- ????????????</wsdl:input>??
- ????????????<wsdl:output?name="sayHelloResponse"?message="tns:sayHelloResponse">??
- ????????????</wsdl:output>??
- ????????</wsdl:operation>??
- ????</wsdl:portType>??
- ????<wsdl:binding?name="XFireServerHttpBinding"?type="tns:XFireServerPortType">??
- ????????<wsdlsoap:binding?style="document"?mce_style="document"?transport="http://schemas.xmlsoap.org/soap/http"?/>??
- ????????<wsdl:operation?name="sayHello">??
- ????????????<wsdlsoap:operation?soapAction=""?/>??
- ????????????<wsdl:input?name="sayHelloRequest">??
- ????????????????<wsdlsoap:body?use="literal"?/>??
- ????????????</wsdl:input>??
- ????????????<wsdl:output?name="sayHelloResponse">??
- ????????????????<wsdlsoap:body?use="literal"?/>??
- ????????????</wsdl:output>??
- ????????</wsdl:operation>??
- ????</wsdl:binding>??
- ????<wsdl:service?name="XFireServer">??
- ????????<wsdl:port?name="XFireServerHttpPort"?binding="tns:XFireServerHttpBinding">??
- ????????????<wsdlsoap:address?location="http://127.0.0.1:8080/XFire_demo/services/XFireServer"?/>??
- ????????</wsdl:port>??
- ????</wsdl:service>??
- </wsdl:definitions>??
第四种方法
这种方法用到了spring的jar包,是前几天在找XFire+Spring的资料的时候看到的,在这里也是做个记录。同样的,这种方法和上面所提到的第二种方法在客户端都需要与服务器一样的接口,包名也必须一样。
(1)在src目录下新建client.xml(名字并非特定)
?
Java代码??
- <span?style="font-family:?'Microsoft?YaHei';"><?xml?version="1.0"?encoding="UTF-8"?>????
- <!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd">????
- <beans>????
- ????<bean?id="baseService"?class="org.codehaus.xfire.spring.remoting.XFireClientFactoryBean"?lazy-init="false"?abstract="true"/>??
- <!--????id的名字作为标识,用于客户端程序中获取service,若有多个service咋在下面添加多个bean即可-->??
- ????<bean?id="MathService"?parent="baseService">??
- ????????<property?name="serviceClass">??
- ????????????<value>service.MathService</value>??
- ????????</property>??
- ????????<property?name="wsdlDocumentUrl">??
- ????????????<value>http://localhost:8080/myservice/mathWebService?wsdl</value>??
- ????????</property>??
- ????</bean>??
- </beans>?</span>??
(2)在程序中调用服务代码非常简单
?
?
Java代码??
- ApplicationContext?ctx?=?new?ClassPathXmlApplicationContext("client.xml");??
- ??
- MathService?mathService?=?(MathService)ctx.getBean("MathService");??
- int?result?=?mathService.add(int?one,int?two);??
?
第五种办法?
先获取到wsdl文件,命名为mathWebService.wsdl放在客户端的src目录下,接着通过程序访问该wsdl文件,并调用需要的方法。
?
Java代码??
- String?wsdl??=???"mathWebService.wsdl?"?;??//?对应的WSDL文件???
- ???????Resource?resource??=???new??ClassPathResource(wsdl);???
- ???????Client?client??=???new??Client(resource.getInputStream(),??null?);??//?根据WSDL创建客户实例???
- ?????????
- ???????Object[]?objArray??=???new??Object[?2?];??
- ???????objArray[?0?]??=???2?;??
- ???????obiArray[1]?=?3;??
- ????????//?调用特定的Web?Service方法???
- ???????Object[]?results??=??client.invoke(?"?add?"?,?objArray);??
- ???????System.out.println(?"?result:??"???+??results[?0?]);??
?
对于这几种方法,第一种方法如果传递的参数为服务器端的实体对象,这点好像比较麻烦,不知道在客户端建立和服务器端相同的实体类行不行,没有实践,返回结果如果是复杂数据类型的话不知道有没有什么问题,或者如何转换,没有深入研究。而且我个人觉得方法调用不是那么直观。第三种方法里面
- wsdl="http://127.0.0.1:8080/XFire_demo/services/XFireServer?wsdl"?
?
这个地方我不知道如何添加多个链接,有知道的朋友希望能指明一下,谢谢了。如果只能有这一个服务,那就太了。其他的方法倒是不觉得有什么大问题,性能什么的差异并未关注,欢迎大家讨论。