WebService开发指南


Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第1页 共207 页 WebWebWebWeb Service Service Service Service 开发指南 VVVV 2.42.42.42.4 作 者 ProdigyWitProdigyWitProdigyWitProdigyWit (QQ:3562720) AlongAlongAlongAlong (QQ:36224205) 版权说明版权说明版权说明版权说明 本文档版权归原作者所有。 在免费的前提下,可在网络媒体中自由传播。 如果需要部分或者全文引用,请注明出处。 官方网址:http://www.hlmz.org 官方 QQ群:3961326 文档版本更新说明文档版本更新说明文档版本更新说明文档版本更新说明 本文档参考并引用了以下著作本文档参考并引用了以下著作本文档参考并引用了以下著作本文档参考并引用了以下著作 版本号 发布时间 说明 V2.4 2009-04-02 加入第 5章整合篇 V2.3 2009-03-06 加入 2.6、2.7 节——Client.NoSOAPAction 处理和服务端 带头信息进行响应 V2.2 2009-02-16 加入 3.6 节——SOAP 头验证和通过 WSDL规范进行服务 端代码生成,Axis 读取头信息 V2.1 2008-12-16 加入 XFire 的使用 WSDL 生成客户端。 V2.0 2008-08-01 加入 XFire 和CXF 使用,做为《Web Service 开发指南》 发布。 V1.0 2008-07-15 做为《AXIS 开发指南》发布。 著作名 著作日期 作者 Axis Webservice 教程 未知 未知 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第2页 共207 页 目录目录目录目录 WEBWEBWEBWEB SERVICE SERVICE SERVICE SERVICE 开发指南................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ 1 版权说明............................................................................................................................................. 1 文档版本更新说明............................................................................................................................. 1 本文档参考并引用了以下著作......................................................................................................... 1 目录..................................................................................................................................................... 2 1.WEBSERVICE 1.WEBSERVICE 1.WEBSERVICE 1.WEBSERVICE 简介........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ 4 1.1 WEBSERVICE 介绍......................................................................................................................... 4 1.2 WEBSERVICE 的开源实现............................................................................................................. 4 2.AXIS 2.AXIS 2.AXIS 2.AXIS 篇篇篇篇................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................4 2.1AXIS 使用......................................................................................................................................4 2.1 .1AXIS 的介绍...........................................................................................................................4 2.1.2 AXIS 的下载...........................................................................................................................4 2.1.3 AXIS 的安装...........................................................................................................................5 2.1.4 开发自己的 WebService........................................................................................................7 2.1.4.1 即时发布——JWS(Java Web Service )......................................................................................... 7 2.1.4.2 定制发布——WSDD.....................................................................................................................9 2.1.4.3 取消发布一个 WebService.........................................................................................................12 2.2.WSDD 高级特性...................................................................................................................... 12 2.2.1 WSDD 的高级特性............................................................................................................12 2.2.2 高级特性 Handler.............................................................................................................13 2.2.4 高级特性 Chain................................................................................................................ 16 2.2.5 传递复杂对象...................................................................................................................21 2.2.5.1 List、Map、数组和自定义对象................................................................................................ 21 2.2.5.2 带内部类的自定义对象..............................................................................................................37 2.2.5.3 RMI 方式远程调用..................................................................................................................... 55 2.2.6 抛出异常...........................................................................................................................58 2.2.7 传递文件...........................................................................................................................65 2.3.AXIS 的常用的命令和调试工具的使用.................................................................................69 2.3.1 AXIS 的常用命令:...........................................................................................................69 2.3.2 调试工具的使用...............................................................................................................70 2.4.AXIS 通过 WSDL 生成服务端代码.........................................................................................71 2.5 AXIS1.4 读取头信息............................................................................................................... 72 2.6 .NET 访问 AXIS 的出现 CLIENT.NOSOAPACTION 的解决方案...................................................75 2.7 AXIS 服务端返回 SOAP HEADER 给客户端.............................................................................. 75 3.3.3.3. XFIE 篇................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ 78 3.1 XFIRE 的简介............................................................................................................................78 3.2 简单的应用.............................................................................................................................. 79 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第3页 共207 页 3.3 传递复杂对象.......................................................................................................................... 83 3.3.1 List、Map、数组和自定义对象....................................................................................83 3.3.1.1 在对象里包含的 List,Map,数组..........................................................................................83 3.3.1.2 传递 Map.....................................................................................................................................94 3.3.2 异常处理.......................................................................................................................101 3.3.3 Handler 处理..................................................................................................................106 3.3.4 文件上传处理...............................................................................................................114 3.4 XFIRE与SPRING 集成............................................................................................................122 3.5 使用 WSDL 生成客户端........................................................................................................ 127 3.6.SOAP 头进行验证................................................................................................................ 131 4.CXF 4.CXF 4.CXF 4.CXF 篇篇篇篇....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................135 4.1 CXF 简介.............................................................................................................................. 135 4.1.1 CXF 的由来................................................................................................................... 135 4.1.2 CXF 的功能................................................................................................................... 135 4.2 CXF 开发.............................................................................................................................. 136 4.2.1 开发环境.......................................................................................................................136 4.2.2 简单的 CXF 应用......................................................................................................... 136 4.2.3 CXF 对请求的拦截处理............................................................................................... 140 4.2.4 CXF 和Spring 集成开发...............................................................................................147 4.2.4.1 List、Map、数组和自定义对象............................................................................................ 148 5555....整合篇整合篇整合篇整合篇.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... 165 5.1 简介....................................................................................................................................... 165 5.2 整合使用.............................................................................................................................. 166 6666.后话............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ 207 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第4页 共207 页 1.WebService 1.WebService 1.WebService 1.WebService 简介 1.11.11.11.1 WebService WebService WebService WebService 介绍介绍介绍介绍 WebService 让一个程序可以透明地调用互联网的程序,不用管具体的实现细节。只要 WebService公开了服务接口,远程客户端就可以调用服务。WebService是基于http 协议的 组件服务,WebService 是分散式应用程序的发展趋势。 1.21.21.21.2 WebService WebService WebService WebService 的开源实现的开源实现的开源实现的开源实现 WebService 更多是一种标准,而不是一种具体的技术。不同的平台,不同的语言大都 提供 WebService 的开发实现。在JAVA领域,WebService的框架很多,例如:Axis1&2、XFire、 CXF……。其中一个成熟实现是AXIS。AXIS应用比较广泛,而且资料相对也比较多。 2.AXIS 2.AXIS 2.AXIS 2.AXIS 篇篇篇篇 2.1AXIS 2.1AXIS 2.1AXIS 2.1AXIS 使用使用使用使用 2.12.12.12.1 .1AXIS .1AXIS .1AXIS .1AXIS 的介绍 Axis(AAAApache eXXXXtensible IIIInteraction SSSSystem)是一款开源的 WebService 运行引擎,它是 SOAP 协议的一个实现,其本身来源于 Apache 的另一个项目 Apache SOAP。Axis 分为 1.x 系列和 2系列,两个系列体系结构和使用上有较大的区别,相对而言,Axis1.x 更加稳定, 文档也比较齐全,因此本文内容以 Axis 1.x 系列最新版本 1.4 为基础。 2.1.22.1.22.1.22.1.2 AXIS AXIS AXIS AXIS 的下载 登陆http://www.apache.org/dyn/closer.cgi/ws/axis/1_4 站 点 ,Axis 的版本是1.4, 本文的例子都是基于该版本完成的。下载axis-bin-1_4.zip 文件,解压改文件,文件结构 如下: Docs:存放Axis 的说明文档。 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第5页 共207 页 Lib:存放Axis 的二进制发布包。 Samples:存放利用Axis 发布的WebService 的示例代码。 Webapps:存放安装Axis 的基础应用。 Xmls:存放相关说明文档。 2.1.32.1.32.1.32.1.3 AXIS AXIS AXIS AXIS 的安装 安装Axis,首先必须保证系统已经正确安装web 服务器,本人使用的Tomcat5.0.28。也 可使用其他应用服务器,例如:weblogic。Webapps下的Axis路径全部复制到Tomcat的Webapps 下。然后打开浏览器:http://127.0.0.1:8080/axis。 如果出现如图所示界面则表示已经安装成功了。 然后点击上面页面的”Validation”连接,如图: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第6页 共207 页 该页显示Axis 的必需组件还缺少一个没有安装,两个可选组件也没有安装,单击上面的提 示: 必需组件: http://java.sun.com/products/javabeans/glasgow/jaf.html 可选组件: http://java.sun.com/products/javamail/ http://xml.apache.org/security/ 分别下载:jaf-1_1-fr.zip,javamail-1_4.zip,xml-security-bin-1_2_1.zip包,然后把 jaf-1_1-fr.zip里的Activation.jar,javamail-1_4.zip里的mail.jar,xml-security-bin- 1_2_1.zip里的xmlsec-1.2.1.jar,xalan.jar都放到你的axis应用的WEB-INF/lib下然后在 校验Axis,看到页面提示全部安装成功。 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第7页 共207 页 2.1.42.1.42.1.42.1.4 开发自己的 WebServiceWebServiceWebServiceWebService AXIS 提供了两种发布方式: � 即时发布(Instant Deployment) � 定制发布( Custom Deployment) 即时发布提供了一种非常简单的WebService的发布方式,但是其中限制太多,因此在实 际的开发中定制发布才是首选。这里也将会以定制发布为重点来介绍。 2.1.4.12.1.4.12.1.4.12.1.4.1 即时发布即时发布即时发布即时发布————————JWS(JavaJWS(JavaJWS(JavaJWS(Java WebWebWebWeb ServiceServiceServiceService )))) 即时发布提供了一种非常简单发布方式,发布者只要有Java源代码(也就是.java文件), 然后把其后缀名改成jws (也就是Java Web Service 的缩写)拷贝到 %TOMCAT_HOME%\webapps\axis目录下即完成了所有的发布工作。AXIS的编译引擎会处理接下 来的所有事情。下面是一段示例代码: 服务端: Java代码: /** *JWS方式WebService服务类 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第8页 共207 页 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-10 */ publicpublicpublicpublicclassclassclassclassHelloWorldJWS{ publicpublicpublicpublicStringtest(Stringa,Integerb){ Stringresult="a="+a+",b="+b; System.out.println("Received:"+result); returnreturnreturnreturn"ServerResponseOK,yousend:"+result; } } 把HelloWorldJWS.java 文件改成HelloWorldJWS.jws 然后拷贝到 %TOMCAT_HOME%\webapps\axis 目录下,启动Tomcat 之后 访 问 http://localhost:8080/axis/HelloWorldJWS.jws如果能看到Click to see the WSDL这个 超链接,就说明已经发布成功了。点击进去就可以看到这个WebService的WSDL描述文件。 Server端的发布已经完成了,接下来就是编写Client端测试代码了。 客户端: Java代码: importimportimportimportjava.rmi.RemoteException; importimportimportimportjavax.xml.namespace.QName; importimportimportimportjavax.xml.rpc.ServiceException; importimportimportimportorg.apache.axis.client.Call; importimportimportimportorg.apache.axis.client.Service; publicpublicpublicpublicclassclassclassclassClientJWS{ /** *@param@param@param@paramargs */ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ trytrytrytry{ Stringurl= "http://127.0.0.1:8080/myaxis/HelloWorldJWS.jws"; Serviceserv=newnewnewnewService(); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第9页 共207 页 Callcall=(Call)serv.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(newnewnewnewQName(url,"test")); Stringresult=(String)call.invoke(newnewnewnew Object[]{"Quahilong",100}); System.out.println("result="+result); }catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); }catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } } 测试代码很简单,如果熟悉java反射机制的朋友不用两分钟就能看明白。运行后客户端控制 台出现以下运行结果。果然很简单吧,不过在这简单背后却是以牺牲灵活性为代价的。 运行结果: 客户端: result=ServerResponseOK,yousend:a=Quahilong,b=100 注意:假如你现在手里只有.class 或者一个 jar 包,jws 就不再能满足你的需求了,最要命的 就是即时发布不支持带包的类,这点 AXIS 的用户手册上写的也很明白。 2.1.4.22.1.4.22.1.4.22.1.4.2 定制发布定制发布定制发布定制发布————————WSDDWSDDWSDDWSDD 比起即时发布,定制发布更加烦琐也更复杂,但是换来的却是更大的灵活性,因此在实 际项目中定制发布还是不二的选择。定制发布需要你自己编写一个WSDD(Web Service Deployment Descriptor)文件,其实就是一个XML描述文件,稍后会做出介绍。废话不多说 , 我们来看代码: 服务端: Java代码: packagepackagepackagepackagewebservice.axis.wsdd; publicpublicpublicpublicclassclassclassclassHelloWorldWSDD{ privateprivateprivateprivateintintintintrequestCount=0; publicpublicpublicpublicStringhello(Stringname){ requestCount++; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第10页 共207 页 System.out.println("requestCount="+requestCount); System.out.println("Received:"+name); returnreturnreturnreturn"Hello"+name; } publicpublicpublicpublicFloatadd(Floata,floatfloatfloatfloatb){ requestCount++; Stringresult="a="+a+",b="+b; System.out.println("requestCount="+requestCount); System.out.println("Received:"+result); returnreturnreturnreturna+b; } } 一个带包的很简单的类,在eclipse 下编译后按照包名拷到 %TOMCAT_HOME%\webapps\axis\WEB-INF\classes目录下。 以这个类为例,拷贝完之后这个HelloWorldWSDD.class 的路径就是 %TOMCAT_HOME%\webapps\axis\WEBINF\classes\webservice\myaxis\wsdd。PS:如果嫌这样 太麻烦,可以另外建一个Java Web工程用myeclipse的发布工具发布到Tomcat之后,整体一 次性拷贝到WebSericve 的工程中。接下来就需要编写发布文件deploy.wsdd 。到 %TOMCAT_HOME%\webapps\axis\WEB-INF目录下建立这个文件并在其中添加如下内容: XML代码: 简单的介绍下各个节点的含义,“HelloWorldWSDD”当然是这个WebService的名字,后面紧 跟的java:RPC指的是服务类型。这里一共有有4种类型,分别是:RPC,Document,Wrapped 和Message。有兴趣可以看下org.apache.axis.providers这个包和子包下面的类的API文档。 之后的parameter节点第一个当然是指出具体的类,第二个从字面上也很好理解:允许调用 的方法。这里的配置告诉引擎可以调用所有的public方法,当然你也可以自己指定。 编写完配置发布文件之后,cmd打开windows的控制台,进入: %TOMCAT_HOME%\webapps\axis\WEB-INF 目录下键入如下命令: java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient deploy.wsdd Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第11页 共207 页 之后控制台返回Processing file deploy.wsdd 和Done processing 这两段话即说明发布 成功。(此时会在同级目录生成一个server-config.wsdd文件)在这里的AdminClient是AXIS 提供的一个客户端管理工具。至于java.ext.dirs的含义可以去了解一下classloader和JVM 类装载机制方面的知识,在这里就不多解释。还有一点要注意的是在发布的时候Tomcat服务 必须处于启动状态,否则就会抛出一堆无法连接的异常信息。发布成功之后你可以通过访问 http://localhost:8080/axis/servlet/AxisServlet 来查看你所有的定制发布的服务。 客户端代码: Java代码: packagepackagepackagepackagewebservice.axis.wsdd; importimportimportimportjava.rmi.RemoteException; importimportimportimportjavax.xml.namespace.QName; importimportimportimportjavax.xml.rpc.ServiceException; importimportimportimportorg.apache.axis.client.Call; importimportimportimportorg.apache.axis.client.Service; publicpublicpublicpublicclassclassclassclassClientWSDD{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ trytrytrytry{ Stringurl= "http://127.0.0.1:8080/myaxis/services/HelloWorldWSDD"; Serviceserv=newnewnewnewService(); Callcall=(Call)serv.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(newnewnewnewQName(url,"hello")); Stringresult=(String)call.invoke(newnewnewnew Object[]{"Quhailong"}); System.out.println("result="+result); call.setOperationName(newnewnewnewQName(url,"add")); FloatreturnValue=(Float)call.invoke(newnewnewnewObject[]{newnewnewnew Float(3.2),newnewnewnewFloat(2.8)}); System.out.println("returnValue="+returnValue); }catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); }catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第12页 共207 页 } } 运行测试代码,输出以下结果,说明发布成功。仔细观察下发现其实除了那个url之外,即 时发布和定制发布的客户端调用代码基本上都是一样的。定制发布的URL可以在WSDL文件里 找到。其实定制发布还有一些高级特性,这个就留到下一篇再说吧。 运行结果: result=HelloQuhailong returnValue=6.0 2.1.4.32.1.4.32.1.4.32.1.4.3 取消发布一个 取消发布一个 取消发布一个 取消发布一个 WebServiceWebServiceWebServiceWebService 刚才讲了怎么发布一个WebService,但是如何取消没有却没有提。其实取消一个已经发 布的WebService也是非常简单的,我们就刚才的HelloWorld来做例子吧。发布WebService 的时候我们有一个deploy.wsdd文件,当然在取消发布的时候就会有一个undeploy.wsdd文 件。这个文件的内容也很简单,xml的代码如下。 XML代码: 编写完这个xml文件之后,把它同样copy 到%TOMCAT_HOM\webapps\axis\WEB-INF目录下,然 后CMD 打开控制台,在控制台输入一个我们很熟悉的命令: java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient undeploy.wsdd 运行之后得到如下结果说明取消发布成功。 运行结果: 客户端: Processing file undeploy.wsdd Done processing 2.2.WSDD 2.2.WSDD 2.2.WSDD 2.2.WSDD 高级特性高级特性高级特性高级特性 2.2.12.2.12.2.12.2.1 WSDD WSDD WSDD WSDD 的高级特性 说完取消发布之后就来说一下AXIS 的一些高级特性,AXIS 在编写deploy.wsdd 这个文 件时,每个节点下面会有这样一个子节点。 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第13页 共207 页 XML代码: 这个节点配置着你的service object 也就是你WebService服务的那个object ,在后面的 value 里可以有三个选项request、session、application。熟悉Jsp、Servlet、或者EJB 里的SessionBean的朋友应该能很快能明白这个三个配置选项的含义。 � requst:这个选项会让AXIS为每一个SOAP的请求产生一个服务对象,可以想像如果这个 webservice的对象足够复杂,而且SOAP的请求过多,这个选项是非常耗费服务器性能的 。 � session:如果选择了session,程序就会给每个调用这个WebService的客户端创造一个 服务对象。 � application:这个选项最彪悍,程序只会在内存里new出来一个服务对象,然后为所有 WebService客户端服务。很显然这个选项不能储存客户端的一些个性化数据。所以在功 能性上很多时候不能满足要求。 2.2.22.2.22.2.22.2.2 高级特性 HandlerHandlerHandlerHandler 接下来说一下Axis 的Handler 和Chain 机 制 ,Handler 和Chain 是Axis 引擎提供的一 个很强大的工具。假如现在客户有这样一个需求:需要记录某一个WebService被调用的次数 。 这个时候如果在service object 里去实现这个功能,不仅麻烦而且侵入了原有的程序,也 会增加原有程序的不稳定性。有了Handler我们就能很容易的解决这个问题。我们先来编写 handler 的代码。 服务端: Java代码: packagepackagepackagepackagewebservice.axis.wsddhandler; importimportimportimportorg.apache.axis.AxisFault; importimportimportimportorg.apache.axis.MessageContext; importimportimportimportorg.apache.axis.handlers.BasicHandler; /** *WebService的Handle类,可以在WebService每个方法被调用之前或者之后做一些事情。 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-10 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第14页 共207 页 */ publicpublicpublicpublicclassclassclassclassHelloWorldHandlerextendsextendsextendsextendsBasicHandler{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=3562695953982109022L; privateprivateprivateprivatestaticstaticstaticstaticlonglonglonglongCOUNT=0L; privateprivateprivateprivateintintintintrequestCount=0; /* *(non-Javadoc) * *@see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext) */ publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextarg0)throwsthrowsthrowsthrowsAxisFault{ requestCount++; COUNT++; Stringstatus=(String)thisthisthisthis.getOption("status"); System.out.println("HelloWorldHandler'sstatusis:"+status +",COUNT="+COUNT+",HandlerRequestCount="+requestCount); } } BasicHandler是一个抽象类,Axis提供了很多Handler的具体实现,BasicHandler只是其中 最简单的一个。要实现一个自己的handler首先要从继承BasicHandler这个类开始并实现其 中的invoke(MessageContext arg)这个方法。MessageContext可以看成是一个Axis的上下 文,里面存储的是一些Axis 和WebService的基本信息。想了解的朋友可以看一下Axis的API。 编写完Handler代码之后我们连编写发布文件。 XML代码: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第15页 共207 页 发布代码中有这样的一句,细心的朋友一定会发现: 看完这句代码再对比一下Handler的实现代码中的一句,相信大多数人都能明白了。 Java代码: String status = (String) thisthisthisthis.getOption("status"); Handle r通过getOption(String)这个方法拿到了配置文件中我配置的属性值。而我们上述 所做的所有工作对于原来的WebSerivce来说都是透明的,不会对侵入原有的程序当中。一个 Handler可以被多个service所使用,通过这个标签来引用到某一个service 中,这里还要多提一句:既然是一个requestFlow,当然可以加多个Handler。接下来编写测 试代码运行。 客户端: Java代码: packagepackagepackagepackage webservice.axis.wsddhandler; importimportimportimport java.rmi.RemoteException; importimportimportimport javax.xml.namespace.QName; importimportimportimport javax.xml.rpc.ServiceException; importimportimportimport org.apache.axis.client.Call; importimportimportimport org.apache.axis.client.Service; publicpublicpublicpublic classclassclassclass ClientWSDDHandler { publicpublicpublicpublic staticstaticstaticstatic voidvoidvoidvoid main(String[] args) { trytrytrytry { String url = "http://127.0.0.1:8080/myaxis/services/HelloWorldWSDDHandler"; Service serv = newnewnewnew Service(); Call call = (Call) serv.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(newnewnewnew QName(url, "hello")); String result = (String) call.invoke(newnewnewnew Object[]{"Quhailong"}); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第16页 共207 页 System.out.println("result="+result); call.setOperationName(newnewnewnewQName(url,"add")); FloatreturnValue=(Float)call.invoke(newnewnewnewObject[]{newnewnewnew Float(3.2),newnewnewnewFloat(2.8)}); System.out.println("returnValue="+returnValue); }catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); }catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } } 在本地应用服务器上会打出如下语句说明测试成功,而且handler是配置在requestFlow标签 中所以这段代码会在service代码之前先执行。如果要在service之后执行,应该配置在 标签中。 运行结果: 客户端: result=HelloQuhailong returnValue=6.0 服务端: HelloWorldHandler's status is: success, COUNT=1, requestCount=1 requestCount=1 Received: Quhailong HelloWorldHandler's status is: success, COUNT=2, requestCount=2 HelloWorldHandler's status is: success, COUNT=3, requestCount=3 requestCount=1 Received: a=3.2, b=2.8 HelloWorldHandler's status is: success, COUNT=4, requestCount=4 2.2.42.2.42.2.42.2.4 高级特性 ChainChainChainChain 介绍完了Handler再来介绍Chain。从Chain的字面意思就能猜到他实现的一连串Handler 的功能。假如某个service 需要不止一个Handler,或者要根据Client 的情况来选择需要那 些Handler。特别是后一个需求,我们无法用一个或者几个Handler来解决,这个时候我们就 需要来实现了。我们先再编写一个Handler,加上之前的那个Handler我们来组成一 条锁链。 服务端: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第17页 共207 页 Java代码: packagepackagepackagepackagewebservice.axis.wsddchain; importimportimportimportorg.apache.axis.AxisFault; importimportimportimportorg.apache.axis.MessageContext; importimportimportimportorg.apache.axis.handlers.BasicHandler; /** *WebService的Handle类,可以在WebService每个方法被调用之前或者之後做一些事情。 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-10 */ publicpublicpublicpublicclassclassclassclassHelloWorldHandler2extendsextendsextendsextendsBasicHandler{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=772997192033702477L; privateprivateprivateprivatestaticstaticstaticstaticlonglonglonglongCOUNT=0L; privateprivateprivateprivateintintintintrequestCount=0; /* *(non-Javadoc) * *@see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext) */ publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextarg0)throwsthrowsthrowsthrowsAxisFault{ requestCount++; COUNT++; Stringstatus=(String)thisthisthisthis.getOption("status"); System.out.println("Thisisanotherhandler. HelloWorldHandler2'sstatusis:"+status+",COUNT="+COUNT+", HandlerRequestCount="+requestCount); } } 之后我们编写 Chain 的代码. 服务端: Java 代码: packagepackagepackagepackagewebservice.axis.wsddchain; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第18页 共207 页 importimportimportimportorg.apache.axis.SimpleChain; importimportimportimportwebservice.axis.wsddhandler.HelloWorldHandler; /** *WebService的Handle链,可以在WebService每个方法被调用之前或之後执行多个 Handler。 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-10 */ publicpublicpublicpublicclassclassclassclassHelloWorldChainextendsextendsextendsextendsSimpleChain{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=-510326708903517617L; publicpublicpublicpublicHelloWorldChain(){ HelloWorldHandlerhandler1=newnewnewnewHelloWorldHandler(); HelloWorldHandler2handler2=newnewnewnewHelloWorldHandler2(); thisthisthisthis.addHandler(handler1); thisthisthisthis.addHandler(handler2); } } 在Chain 的构造函数中,把我要的两个Handler用addHandler()方法加载进去。之后我们来 编写发布文件。元素有些许不同在这里有必要多句嘴:元素中 的子元素只允许是或者。后者也就是允许在“锁链”里再嵌套“锁链”, 在这里就拿嵌套来举例,他同样有两种方式来实现。 第一种是直接包含: 第二种是引用别的: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第19页 共207 页 因为我们这里的HelloWorldChain并没有由BasicHandler 来实现,而是由继承 SimpleChain这个类来实现,严格意义上讲,SimpleChain也可以算是一个Handler,因为 SimpleChain也是从 BasicHandler继承而来,他同样实现了invoke()这个方法。下面回归正题,来看我们的发布 代码。 XML代码: 从新发布WebService之后,运行我们的测试代码。 客户端: Java代码: packagepackagepackagepackagewebservice.axis.wsddchain; importimportimportimportjava.rmi.RemoteException; importimportimportimportjavax.xml.namespace.QName; importimportimportimportjavax.xml.rpc.ServiceException; importimportimportimportorg.apache.axis.client.Call; importimportimportimportorg.apache.axis.client.Service; publicpublicpublicpublicclassclassclassclassClientWSDDChain{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ trytrytrytry{ Stringurl= "http://127.0.0.1:8080/myaxis/services/HelloWorldWSDDChain"; Serviceserv=newnewnewnewService(); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第20页 共207 页 Callcall=(Call)serv.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(newnewnewnewQName(url,"hello")); Stringresult=(String)call.invoke(newnewnewnew Object[]{"Quhailong"}); System.out.println("result="+result); call.setOperationName(newnewnewnewQName(url,"add")); FloatreturnValue=(Float)call.invoke(newnewnewnewObject[]{newnewnewnew Float(3.2),newnewnewnewFloat(2.8)}); System.out.println("returnValue="+returnValue); }catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); }catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } } 结果如下: 运行结果: 客户端: result=HelloQuhailong returnValue=6.0 服务端: HelloWorldHandler's status is: null, COUNT=7, requestCount=3 This is an other handler. HelloWorldHandler2's status is: null, COUNT=3, requestCount=3 requestCount=1 Received: Quhailong HelloWorldHandler's status is: null, COUNT=8, requestCount=4 This is an other handler. HelloWorldHandler2's status is: null, COUNT=4, requestCount=4 requestCount=1 Received: a=3.2, b=2.8 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第21页 共207 页 2.2.52.2.52.2.52.2.5 传递复杂对象 2.2.5.12.2.5.12.2.5.12.2.5.1 ListListListList、、、、MapMapMapMap、数组和自定义对象、数组和自定义对象、数组和自定义对象、数组和自定义对象 在上面介绍Axis的文章里,我们做了一个简单的WebService,我们client side传递了 String和int类型的数据给service object。Service 处理之后返回处理结果给Client。对 于大多数需求,那个demo显然已经足够应付了。但是如果client端需要传输一个对象给 server,那么那个demo 就显得力不从心了。Axis中提供了远程传输对象的方法,通过那些 方法我们同样可以随心的传递自己的对象。 先看下面的 JAVABEAN 这个对象是服务端的对象: Java 代码: importimportimportimportjava.io.Serializable; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.List; /** *服务端的自定义类型 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassAddressimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=5182870829593983607L; privateprivateprivateprivateIntegeridentifier; /**地址 */ privateprivateprivateprivateStringaddress; /**城市 */ privateprivateprivateprivateStringcity; /**省份 */ privateprivateprivateprivateStringprovince; /**国家 */ privateprivateprivateprivateStringcountry; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第22页 共207 页 /**邮编 */ privateprivateprivateprivateStringpostalCode; privateprivateprivateprivateString[]array; privateprivateprivateprivateListlist; privateprivateprivateprivatebooleanbooleanbooleanbooleanisExist; publicpublicpublicpublicAddress(){ list=newnewnewnewArrayList(); list.add(1); list.add(2); list.add(3); } publicpublicpublicpublicIntegergetIdentifier(){ returnreturnreturnreturnidentifier; } publicpublicpublicpublicvoidvoidvoidvoidsetIdentifier(Integeridentifier){ thisthisthisthis.identifier=identifier; } publicpublicpublicpublicStringgetAddress(){ returnreturnreturnreturnaddress; } publicpublicpublicpublicvoidvoidvoidvoidsetAddress(Stringaddress){ thisthisthisthis.address=address; } publicpublicpublicpublicStringgetCity(){ returnreturnreturnreturncity; } publicpublicpublicpublicvoidvoidvoidvoidsetCity(Stringcity){ thisthisthisthis.city=city; } publicpublicpublicpublicStringgetProvince(){ returnreturnreturnreturnprovince; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第23页 共207 页 publicpublicpublicpublicvoidvoidvoidvoidsetProvince(Stringprovince){ thisthisthisthis.province=province; } publicpublicpublicpublicStringgetCountry(){ returnreturnreturnreturncountry; } publicpublicpublicpublicvoidvoidvoidvoidsetCountry(Stringcountry){ thisthisthisthis.country=country; } publicpublicpublicpublicStringgetPostalCode(){ returnreturnreturnreturnpostalCode; } publicpublicpublicpublicvoidvoidvoidvoidsetPostalCode(StringpostalCode){ thisthisthisthis.postalCode=postalCode; } publicpublicpublicpublicString[]getArray(){ returnreturnreturnreturnarray; } publicpublicpublicpublicvoidvoidvoidvoidsetArray(String[]array){ thisthisthisthis.array=array; } publicpublicpublicpublicbooleanbooleanbooleanbooleanisExist(){ returnreturnreturnreturnisExist; } publicpublicpublicpublicvoidvoidvoidvoidsetExist(booleanbooleanbooleanbooleanisExist){ thisthisthisthis.isExist=isExist; } publicpublicpublicpublicListgetList(){ returnreturnreturnreturnlist; } publicpublicpublicpublicvoidvoidvoidvoidsetList(Listlist){ thisthisthisthis.list=list; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第24页 共207 页 } 注意:所有要传递的对象都要是可序化的。 服务端的业务: Java 代码: importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.List; importimportimportimportjava.util.Map; importimportimportimportwebservice.axis.wsddselfobj.servermodel.Address; /** *提供List的WebService业务 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassAddressManager{ publicpublicpublicpublicList
getAddressList(){ List
returnList=newnewnewnewArrayList
(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); returnList.add(address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第25页 共207 页 address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); returnList.add(address); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); returnreturnreturnreturnreturnList; } publicpublicpublicpublicList
setAddressList(List
list){ returnreturnreturnreturnlist; } publicpublicpublicpublicMapgetAddressMap(){ MapreturnMap=newnewnewnewHashMap(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); returnMap.put(address.getIdentifier(),address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); returnMap.put(address.getIdentifier(),address); returnreturnreturnreturnreturnMap; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第26页 共207 页 publicpublicpublicpublicMapsetAddressMap(Map map){ returnreturnreturnreturnmap; } } 下面的客户端和客户端的 JAVABEAN 客户端 JAVABEAN: Java 代码: importimportimportimportjava.io.Serializable; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.List; /** *客户端的自定义类型 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassAddressimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=5182870829593983607L; privateprivateprivateprivateIntegeridentifier; /**地址 */ privateprivateprivateprivateStringaddress; /**城市 */ privateprivateprivateprivateStringcity; /**省份 */ privateprivateprivateprivateStringprovince; /**国家 */ privateprivateprivateprivateStringcountry; /**邮编 */ privateprivateprivateprivateStringpostalCode; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第27页 共207 页 privateprivateprivateprivateString[]array; privateprivateprivateprivateListlist; privateprivateprivateprivatebooleanbooleanbooleanbooleanisExist; publicpublicpublicpublicAddress(){ list=newnewnewnewArrayList(); list.add(1); list.add(2); list.add(3); } publicpublicpublicpublicIntegergetIdentifier(){ returnreturnreturnreturnidentifier; } publicpublicpublicpublicvoidvoidvoidvoidsetIdentifier(Integeridentifier){ thisthisthisthis.identifier=identifier; } publicpublicpublicpublicStringgetAddress(){ returnreturnreturnreturnaddress; } publicpublicpublicpublicvoidvoidvoidvoidsetAddress(Stringaddress){ thisthisthisthis.address=address; } publicpublicpublicpublicStringgetCity(){ returnreturnreturnreturncity; } publicpublicpublicpublicvoidvoidvoidvoidsetCity(Stringcity){ thisthisthisthis.city=city; } publicpublicpublicpublicStringgetProvince(){ returnreturnreturnreturnprovince; } publicpublicpublicpublicvoidvoidvoidvoidsetProvince(Stringprovince){ thisthisthisthis.province=province; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第28页 共207 页 publicpublicpublicpublicStringgetCountry(){ returnreturnreturnreturncountry; } publicpublicpublicpublicvoidvoidvoidvoidsetCountry(Stringcountry){ thisthisthisthis.country=country; } publicpublicpublicpublicStringgetPostalCode(){ returnreturnreturnreturnpostalCode; } publicpublicpublicpublicvoidvoidvoidvoidsetPostalCode(StringpostalCode){ thisthisthisthis.postalCode=postalCode; } publicpublicpublicpublicString[]getArray(){ returnreturnreturnreturnarray; } publicpublicpublicpublicvoidvoidvoidvoidsetArray(String[]array){ thisthisthisthis.array=array; } publicpublicpublicpublicbooleanbooleanbooleanbooleanisExist(){ returnreturnreturnreturnisExist; } publicpublicpublicpublicvoidvoidvoidvoidsetExist(booleanbooleanbooleanbooleanisExist){ thisthisthisthis.isExist=isExist; } publicpublicpublicpublicListgetList(){ returnreturnreturnreturnlist; } publicpublicpublicpublicvoidvoidvoidvoidsetList(Listlist){ thisthisthisthis.list=list; } } 客户端: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第29页 共207 页 Java 代码: importimportimportimportjava.net.MalformedURLException; importimportimportimportjava.rmi.RemoteException; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.Iterator; importimportimportimportjava.util.List; importimportimportimportjava.util.Map; importimportimportimportjavax.xml.namespace.QName; importimportimportimportjavax.xml.rpc.ParameterMode; importimportimportimportjavax.xml.rpc.ServiceException; importimportimportimportorg.apache.axis.client.Call; importimportimportimportorg.apache.axis.client.Service; importimportimportimportorg.apache.axis.encoding.XMLType; importimportimportimportwebservice.axis.wsddselfobj.clientmodel.Address; /** *获得WebService的返回List/Map对象的客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ @SuppressWarnings("unchecked") publicpublicpublicpublicclassclassclassclassClientAddress{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidgetServerList(){ Stringurl= "http://127.0.0.1:8080/axis/services/AddressManager"; Serviceservice=newnewnewnewService(); trytrytrytry{ Callcall=(Call)service.createCall(); QNameqn=newnewnewnewQName("urn:AddressManager","Address"); call.registerTypeMapping(Address.classclassclassclass,qn, newnewnewnew org.apache.axis.encoding.ser.BeanSerializerFactory( Address.classclassclassclass,qn), Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第30页 共207 页 newnewnewnew org.apache.axis.encoding.ser.BeanDeserializerFactory( Address.classclassclassclass,qn)); call.setTargetEndpointAddress(newnewnewnewjava.net.URL(url)); call.setOperationName(newnewnewnewQName("AddressManager", "getAddressList")); call.setReturnClass(ArrayList.classclassclassclass); Object[]sss=nullnullnullnull; List
list=(ArrayList)call.invoke(sss); System.out.println("Listsize:"+list.size()); forforforfor(Iterator
iter=list.iterator(); iter.hasNext();){ Addressaddress=iter.next(); System.out.println("id号:"+address.getIdentifier() +"address:"+address.getAddress() +"city:"+address.getCity() +"country:"+address.getCountry() +"postalCode:"+address.getPostalCode() +"province:"+address.getProvince() +"array:"+address.getArray()[0] +"list:"+address.getList() +"isExist:"+address.isExist()); } } catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidsetServerList(){ Stringurl= "http://127.0.0.1:8080/axis/services/AddressManager"; Serviceservice=newnewnewnewService(); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第31页 共207 页 List
list=newnewnewnewArrayList
(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); list.add(address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); list.add(address); trytrytrytry{ Callcall=(Call)service.createCall(); QNameqn=newnewnewnewQName("urn:AddressManager","Address"); call.registerTypeMapping(Address.classclassclassclass,qn, newnewnewnew org.apache.axis.encoding.ser.BeanSerializerFactory( Address.classclassclassclass,qn), newnewnewnew org.apache.axis.encoding.ser.BeanDeserializerFactory( Address.classclassclassclass,qn)); call.setTargetEndpointAddress(newnewnewnewjava.net.URL(url)); call.setOperationName(newnewnewnewQName("AddressManager", "setAddressList")); call.setReturnClass(ArrayList.classclassclassclass); call.addParameter("list",XMLType.XSD_ANYTYPE, ParameterMode.IN); list=(ArrayList)call.invoke(newnewnewnewObject[]{list}); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第32页 共207 页 System.out.println("Listsize:"+list.size()); forforforfor(Iterator
iter=list.iterator(); iter.hasNext();){ address=iter.next(); System.out.println("id号:"+address.getIdentifier() +"address:"+address.getAddress() +"city:"+address.getCity() +"country:"+address.getCountry() +"postalCode:"+address.getPostalCode() +"province:"+address.getProvince() +"array:"+address.getArray()[0] +"list:"+address.getList() +"isExist:"+address.isExist()); } } catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidgetServerMap(){ Stringurl= "http://127.0.0.1:8080/axis/services/AddressManager"; Serviceservice=newnewnewnewService(); trytrytrytry{ Callcall=(Call)service.createCall(); QNameqn=newnewnewnewQName("urn:AddressManager","Address"); call.registerTypeMapping(Address.classclassclassclass,qn, newnewnewnew org.apache.axis.encoding.ser.BeanSerializerFactory( Address.classclassclassclass,qn), newnewnewnew org.apache.axis.encoding.ser.BeanDeserializerFactory( Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第33页 共207 页 Address.classclassclassclass,qn)); call.setTargetEndpointAddress(newnewnewnewjava.net.URL(url)); Object[]sss=nullnullnullnull; call.setOperationName(newnewnewnewQName("AddressManager", "getAddressMap")); call.setReturnClass(HashMap.classclassclassclass); Mapmap=(Map)call.invoke(sss); System.out.println("Mapsize:"+map.size()); forforforfor(Iteratoriter=map.keySet().iterator(); iter.hasNext();){ Integerkey=iter.next(); Addressaddress=map.get(key); System.out.println("id号:"+address.getIdentifier() +"address:"+address.getAddress() +"city:"+address.getCity() +"country:"+address.getCountry() +"postalCode:"+address.getPostalCode() +"province:"+address.getProvince() +"array:"+address.getArray()[0] +"list:"+address.getList() +"isExist:"+address.isExist()); } } catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidsetServerMap(){ Stringurl= "http://127.0.0.1:8080/axis/services/AddressManager"; Serviceservice=newnewnewnewService(); Mapmap=newnewnewnewHashMap(); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第34页 共207 页 Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); map.put(address.getIdentifier(),address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); map.put(address.getIdentifier(),address); trytrytrytry{ Callcall=(Call)service.createCall(); QNameqn=newnewnewnewQName("urn:AddressManager","Address"); call.registerTypeMapping(Address.classclassclassclass,qn, newnewnewnew org.apache.axis.encoding.ser.BeanSerializerFactory( Address.classclassclassclass,qn), newnewnewnew org.apache.axis.encoding.ser.BeanDeserializerFactory( Address.classclassclassclass,qn)); call.setTargetEndpointAddress(newnewnewnewjava.net.URL(url)); call.setOperationName(newnewnewnewQName("AddressManager", "setAddressMap")); call.setReturnClass(HashMap.classclassclassclass); call.addParameter("list",XMLType.XSD_ANYTYPE, ParameterMode.IN); map=(Map)call.invoke(newnewnewnewObject[]{map}); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第35页 共207 页 System.out.println("Mapsize:"+map.size()); forforforfor(Iteratoriter=map.keySet().iterator(); iter.hasNext();){ Integerkey=iter.next(); address=map.get(key); System.out.println("id号:"+address.getIdentifier() +"address:"+address.getAddress() +"city:"+address.getCity() +"country:"+address.getCountry() +"postalCode:"+address.getPostalCode() +"province:"+address.getProvince() +"array:"+address.getArray()[0] +"list:"+address.getList() +"isExist:"+address.isExist()); } } catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ getServerList(); getServerMap(); setServerList(); setServerMap(); } } 以上是客户端和服务端的代码,现在主要介绍一下关于 WSDD,代码如下: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第36页 共207 页 唯一不同的就是多了这个节点。QName表示XML 规范中定义的限定名称,他由 名称空间URI、本地部分和前缀组成。除了本地部分其他都不是必须的,另外QName是不可变 的。xmlns 后面的myNS是必须的。具体根据前面所指定的qname 来决定。之后可以随意命名 一个namespace。最后的languageSpecificType 指定的是你传递的对象类型。第一个属性的 本地部分和第二个节点你自定义的命名空间会组成一个新的QName,并将你要传输的对象 mapping上去。 注意:在上面编写客户端的时候要注意几个问题: � 如果你有返回值的话一定要设置你的返回值类型。 � 如果服务器上的方法有参数一定要指定你的参数类型。 � 一定要拷贝 wsdl4j-1.5.1.jar 否则会报错,找不到你的转换类型。 运行结果: 客户端: Listsize:2 id号:1address:Haidiancity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:1list:[1,2,3]isExist:false id号:2address:Chaoyangcity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:Alist:[1,2,3]isExist:true Mapsize:2 id号:1address:Haidiancity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:1list:[1,2,3]isExist:false id号:2address:Chaoyangcity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:Alist:[1,2,3]isExist:true Listsize:2 id号:1address:Haidiancity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:1list:[1,2,3]isExist:false id号:2address:Chaoyangcity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:Alist:[1,2,3]isExist:true Mapsize:2 id号:1address:Haidiancity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:1list:[1,2,3]isExist:false id号:2address:Chaoyangcity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:Alist:[1,2,3]isExist:true Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第37页 共207 页 2.2.5.2 2.2.5.2 2.2.5.2 2.2.5.2 带内部类的自定义对象带内部类的自定义对象带内部类的自定义对象带内部类的自定义对象 经过上面的了解我们对大部分的 JAVABEAN 对象有了了解,像对返回类型 List、Map。 List 里有 JAVABEAN 等这些都有了相应的解决方案。下面介绍一下特殊的情况,就是对内 部类的使用废话少说来点代码一般就知道了: 服务端的 JAVABEAN: Java 代码: packagepackagepackagepackage webservice.axis.wsddselfobj.servermodel; importimportimportimport java.io.Serializable; importimportimportimport java.util.ArrayList; importimportimportimport java.util.List; /** * 服务端的自定义类型 * *@author@author@author@author Along * *@version@version@version@version $Revision$ * *@since@since@since@since 2008-7-11 */ publicpublicpublicpublic classclassclassclass Address implementsimplementsimplementsimplements Serializable{ privateprivateprivateprivate staticstaticstaticstatic finalfinalfinalfinal longlonglonglong serialVersionUID = 5182870829593983607L; privateprivateprivateprivate Integer identifier; /** 地址 */ privateprivateprivateprivate String address; /** 城市 */ privateprivateprivateprivate String city; /** 省份 */ privateprivateprivateprivate String province; /** 国家 */ privateprivateprivateprivate String country; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第38页 共207 页 /**邮编 */ privateprivateprivateprivateStringpostalCode; privateprivateprivateprivateString[]array; privateprivateprivateprivateListlist; privateprivateprivateprivatebooleanbooleanbooleanbooleanisExist; privateprivateprivateprivateInnerClassinnC; publicpublicpublicpublicstaticstaticstaticstaticclassclassclassclassInnerClassimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=- 2330738090948448510L; privateprivateprivateprivateStringinnerName; publicpublicpublicpublicStringgetInnerName(){ returnreturnreturnreturninnerName; } publicpublicpublicpublicvoidvoidvoidvoidsetInnerName(StringinnerName){ thisthisthisthis.innerName=innerName; } } publicpublicpublicpublicAddress(){ list=newnewnewnewArrayList(); list.add(1); list.add(2); list.add(3); innC=newnewnewnewInnerClass(); innC.setInnerName("MyInnername"); } publicpublicpublicpublicInnerClassgetInnC(){ returnreturnreturnreturninnC; } publicpublicpublicpublicvoidvoidvoidvoidsetInnC(InnerClassinnC){ thisthisthisthis.innC=innC; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第39页 共207 页 publicpublicpublicpublicIntegergetIdentifier(){ returnreturnreturnreturnidentifier; } publicpublicpublicpublicvoidvoidvoidvoidsetIdentifier(Integeridentifier){ thisthisthisthis.identifier=identifier; } publicpublicpublicpublicStringgetAddress(){ returnreturnreturnreturnaddress; } publicpublicpublicpublicvoidvoidvoidvoidsetAddress(Stringaddress){ thisthisthisthis.address=address; } publicpublicpublicpublicStringgetCity(){ returnreturnreturnreturncity; } publicpublicpublicpublicvoidvoidvoidvoidsetCity(Stringcity){ thisthisthisthis.city=city; } publicpublicpublicpublicStringgetProvince(){ returnreturnreturnreturnprovince; } publicpublicpublicpublicvoidvoidvoidvoidsetProvince(Stringprovince){ thisthisthisthis.province=province; } publicpublicpublicpublicStringgetCountry(){ returnreturnreturnreturncountry; } publicpublicpublicpublicvoidvoidvoidvoidsetCountry(Stringcountry){ thisthisthisthis.country=country; } publicpublicpublicpublicStringgetPostalCode(){ returnreturnreturnreturnpostalCode; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第40页 共207 页 publicpublicpublicpublicvoidvoidvoidvoidsetPostalCode(StringpostalCode){ thisthisthisthis.postalCode=postalCode; } publicpublicpublicpublicString[]getArray(){ returnreturnreturnreturnarray; } publicpublicpublicpublicvoidvoidvoidvoidsetArray(String[]array){ thisthisthisthis.array=array; } publicpublicpublicpublicbooleanbooleanbooleanbooleanisExist(){ returnreturnreturnreturnisExist; } publicpublicpublicpublicvoidvoidvoidvoidsetExist(booleanbooleanbooleanbooleanisExist){ thisthisthisthis.isExist=isExist; } publicpublicpublicpublicListgetList(){ returnreturnreturnreturnlist; } publicpublicpublicpublicvoidvoidvoidvoidsetList(Listlist){ thisthisthisthis.list=list; } } 这个类需要值得注意的是 2点: � 内部类必须是可序化的。 � 内部类必须是静态的,否则不能被序列化。 WebService 业务: Java 代码 packagepackagepackagepackagewebservice.axis.wsddselfobj; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.List; importimportimportimportjava.util.Map; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第41页 共207 页 importimportimportimportwebservice.axis.wsddselfobj.servermodel.Address; /** *提供复杂对象的WebService业务 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassAddressManager{ publicpublicpublicpublicList
getAddressList(){ List
returnList=newnewnewnewArrayList
(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); returnList.add(address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); returnList.add(address); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); returnreturnreturnreturnreturnList; } publicpublicpublicpublicList
setAddressList(List
list){ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第42页 共207 页 returnreturnreturnreturnlist; } publicpublicpublicpublicMapgetAddressMap(){ MapreturnMap=newnewnewnewHashMap(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); returnMap.put(address.getIdentifier(),address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); returnMap.put(address.getIdentifier(),address); returnreturnreturnreturnreturnMap; } publicpublicpublicpublicMapsetAddressMap(Map map){ returnreturnreturnreturnmap; } } 上面的业务写法就不在说任何说明了。 客户端的 JAVABEAN Java 代码: packagepackagepackagepackagewebservice.axis.wsddselfobj.clientmodel; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第43页 共207 页 importimportimportimportjava.io.Serializable; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.List; /** *客户端的自定义类型 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassAddressimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=5182870829593983607L; privateprivateprivateprivateIntegeridentifier; /**地址 */ privateprivateprivateprivateStringaddress; /**城市 */ privateprivateprivateprivateStringcity; /**省份 */ privateprivateprivateprivateStringprovince; /**国家 */ privateprivateprivateprivateStringcountry; /**邮编 */ privateprivateprivateprivateStringpostalCode; privateprivateprivateprivateString[]array; privateprivateprivateprivateListlist; privateprivateprivateprivatebooleanbooleanbooleanbooleanisExist; privateprivateprivateprivateInnerClassinnC; publicpublicpublicpublicstaticstaticstaticstaticclassclassclassclassInnerClassimplementsimplementsimplementsimplementsSerializable{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第44页 共207 页 privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=- 2330738090948448510L; privateprivateprivateprivateStringinnerName; publicpublicpublicpublicStringgetInnerName(){ returnreturnreturnreturninnerName; } publicpublicpublicpublicvoidvoidvoidvoidsetInnerName(StringinnerName){ thisthisthisthis.innerName=innerName; } } publicpublicpublicpublicAddress(){ list=newnewnewnewArrayList(); list.add(1); list.add(2); list.add(3); innC=newnewnewnewInnerClass(); innC.setInnerName("MyInnername"); } publicpublicpublicpublicInnerClassgetInnC(){ returnreturnreturnreturninnC; } publicpublicpublicpublicvoidvoidvoidvoidsetInnC(InnerClassinnC){ thisthisthisthis.innC=innC; } publicpublicpublicpublicIntegergetIdentifier(){ returnreturnreturnreturnidentifier; } publicpublicpublicpublicvoidvoidvoidvoidsetIdentifier(Integeridentifier){ thisthisthisthis.identifier=identifier; } publicpublicpublicpublicStringgetAddress(){ returnreturnreturnreturnaddress; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第45页 共207 页 publicpublicpublicpublicvoidvoidvoidvoidsetAddress(Stringaddress){ thisthisthisthis.address=address; } publicpublicpublicpublicStringgetCity(){ returnreturnreturnreturncity; } publicpublicpublicpublicvoidvoidvoidvoidsetCity(Stringcity){ thisthisthisthis.city=city; } publicpublicpublicpublicStringgetProvince(){ returnreturnreturnreturnprovince; } publicpublicpublicpublicvoidvoidvoidvoidsetProvince(Stringprovince){ thisthisthisthis.province=province; } publicpublicpublicpublicStringgetCountry(){ returnreturnreturnreturncountry; } publicpublicpublicpublicvoidvoidvoidvoidsetCountry(Stringcountry){ thisthisthisthis.country=country; } publicpublicpublicpublicStringgetPostalCode(){ returnreturnreturnreturnpostalCode; } publicpublicpublicpublicvoidvoidvoidvoidsetPostalCode(StringpostalCode){ thisthisthisthis.postalCode=postalCode; } publicpublicpublicpublicString[]getArray(){ returnreturnreturnreturnarray; } publicpublicpublicpublicvoidvoidvoidvoidsetArray(String[]array){ thisthisthisthis.array=array; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第46页 共207 页 publicpublicpublicpublicbooleanbooleanbooleanbooleanisExist(){ returnreturnreturnreturnisExist; } publicpublicpublicpublicvoidvoidvoidvoidsetExist(booleanbooleanbooleanbooleanisExist){ thisthisthisthis.isExist=isExist; } publicpublicpublicpublicListgetList(){ returnreturnreturnreturnlist; } publicpublicpublicpublicvoidvoidvoidvoidsetList(Listlist){ thisthisthisthis.list=list; } } 客户端调用: Java 代码: packagepackagepackagepackagewebservice.axis.wsddselfobj; importimportimportimportjava.net.MalformedURLException; importimportimportimportjava.rmi.RemoteException; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.Iterator; importimportimportimportjava.util.List; importimportimportimportjava.util.Map; importimportimportimportjavax.xml.namespace.QName; importimportimportimportjavax.xml.rpc.ParameterMode; importimportimportimportjavax.xml.rpc.ServiceException; importimportimportimportorg.apache.axis.client.Call; importimportimportimportorg.apache.axis.client.Service; importimportimportimportorg.apache.axis.encoding.XMLType; importimportimportimportorg.apache.axis.encoding.ser.BeanDeserializerFactory; importimportimportimportorg.apache.axis.encoding.ser.BeanSerializerFactory; importimportimportimportwebservice.axis.wsddselfobj.clientmodel.Address; /** Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第47页 共207 页 *获得WebService的返回List/Map等负责对象的客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ @SuppressWarnings("unchecked") publicpublicpublicpublicclassclassclassclassClientAddress{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidgetServerList(){ Stringurl= "http://127.0.0.1:8080/myaxis/services/AddressManager"; Serviceservice=newnewnewnewService(); trytrytrytry{ Callcall=(Call)service.createCall(); QNameqn=newnewnewnewQName("urn:AddressManager","Address"); QNameqn1=newnewnewnewQName("urn:AddressInnerClass", "myNSD:InnerClass"); call.registerTypeMapping(Address.classclassclassclass,qn, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); call.registerTypeMapping(Address.InnerClass.classclassclassclass,qn1, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); call.setTargetEndpointAddress(newnewnewnewjava.net.URL(url)); call.setOperationName(newnewnewnewQName("AddressManager", "getAddressList")); call.setReturnClass(ArrayList.classclassclassclass); Object[]sss=nullnullnullnull; List
list=(ArrayList)call.invoke(sss); System.out.println("Listsize:"+list.size()); forforforfor(Iterator
iter=list.iterator(); iter.hasNext();){ Addressaddress=iter.next(); System.out.println("id号:"+address.getIdentifier() +"address:"+address.getAddress() Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第48页 共207 页 +"city:"+address.getCity() +"country:"+address.getCountry() +"postalCode:"+address.getPostalCode() +"province:"+address.getProvince() +"array:"+address.getArray()[0] +"list:"+address.getList() +"isExist:"+address.isExist() +"innerClass.name:"+ address.getInnC().getInnerName()); } } catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidsetServerList(){ Stringurl= "http://127.0.0.1:8080/myaxis/services/AddressManager"; Serviceservice=newnewnewnewService(); List
list=newnewnewnewArrayList
(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); list.add(address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第49页 共207 页 address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); list.add(address); trytrytrytry{ Callcall=(Call)service.createCall(); QNameqn=newnewnewnewQName("urn:AddressManager","Address"); QNameqn1=newnewnewnewQName("urn:AddressInnerClass", "myNSD:InnerClass"); call.registerTypeMapping(Address.classclassclassclass,qn, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); call.registerTypeMapping(Address.InnerClass.classclassclassclass,qn1, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); call.setTargetEndpointAddress(newnewnewnewjava.net.URL(url)); call.setOperationName(newnewnewnewQName("AddressManager", "setAddressList")); call.setReturnClass(ArrayList.classclassclassclass); call.addParameter("list",XMLType.XSD_ANYTYPE, ParameterMode.IN); list=(ArrayList)call.invoke(newnewnewnewObject[]{list}); System.out.println("Listsize:"+list.size()); forforforfor(Iterator
iter=list.iterator(); iter.hasNext();){ address=iter.next(); System.out.println("id号:"+address.getIdentifier() +"address:"+address.getAddress() +"city:"+address.getCity() +"country:"+address.getCountry() +"postalCode:"+address.getPostalCode() +"province:"+address.getProvince() +"array:"+address.getArray()[0] +"list:"+address.getList() +"isExist:"+address.isExist() +"innerClass.name:"+ address.getInnC().getInnerName()); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第50页 共207 页 } } catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidgetServerMap(){ Stringurl= "http://127.0.0.1:8080/myaxis/services/AddressManager"; Serviceservice=newnewnewnewService(); trytrytrytry{ Callcall=(Call)service.createCall(); QNameqn=newnewnewnewQName("urn:AddressManager","Address"); QNameqn1=newnewnewnewQName("urn:AddressInnerClass", "myNSD:InnerClass"); call.registerTypeMapping(Address.classclassclassclass,qn, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); call.registerTypeMapping(Address.InnerClass.classclassclassclass,qn1, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); call.setTargetEndpointAddress(newnewnewnewjava.net.URL(url)); Object[]sss=nullnullnullnull; call.setOperationName(newnewnewnewQName("AddressManager", "getAddressMap")); call.setReturnClass(HashMap.classclassclassclass); Mapmap=(Map)call.invoke(sss); System.out.println("Mapsize:"+map.size()); forforforfor(Iteratoriter=map.keySet().iterator(); iter.hasNext();){ Integerkey=iter.next(); Addressaddress=map.get(key); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第51页 共207 页 System.out.println("id号:"+address.getIdentifier() +"address:"+address.getAddress() +"city:"+address.getCity() +"country:"+address.getCountry() +"postalCode:"+address.getPostalCode() +"province:"+address.getProvince() +"array:"+address.getArray()[0] +"list:"+address.getList() +"isExist:"+address.isExist() +"innerClass.name:"+ address.getInnC().getInnerName()); } } catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidsetServerMap(){ Stringurl= "http://127.0.0.1:8080/myaxis/services/AddressManager"; Serviceservice=newnewnewnewService(); Mapmap=newnewnewnewHashMap(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); map.put(address.getIdentifier(),address); address=newnewnewnewAddress(); address.setIdentifier(2); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第52页 共207 页 address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); map.put(address.getIdentifier(),address); trytrytrytry{ Callcall=(Call)service.createCall(); QNameqn=newnewnewnewQName("urn:AddressManager","Address"); QNameqn1=newnewnewnewQName("urn:AddressInnerClass", "myNSD:InnerClass"); call.registerTypeMapping(Address.classclassclassclass,qn, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); call.registerTypeMapping(Address.InnerClass.classclassclassclass,qn1, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); call.setTargetEndpointAddress(newnewnewnewjava.net.URL(url)); call.setOperationName(newnewnewnewQName("AddressManager", "setAddressMap")); call.setReturnClass(HashMap.classclassclassclass); call.addParameter("list",XMLType.XSD_ANYTYPE, ParameterMode.IN); map=(Map)call.invoke(newnewnewnewObject[]{map}); System.out.println("Mapsize:"+map.size()); forforforfor(Iteratoriter=map.keySet().iterator(); iter.hasNext();){ Integerkey=iter.next(); address=map.get(key); System.out.println("id号:"+address.getIdentifier() +"address:"+address.getAddress() +"city:"+address.getCity() +"country:"+address.getCountry() +"postalCode:"+address.getPostalCode() +"province:"+address.getProvince() +"array:"+address.getArray()[0] +"list:"+address.getList() Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第53页 共207 页 +"isExist:"+address.isExist() +"innerClass.name:"+ address.getInnC().getInnerName()); } } catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ getServerList(); getServerMap(); setServerList(); setServerMap(); } } 这个地方需要啰嗦几句: 关于 Address 这个类由于他里面有一个内部类,但是这个内部类里并不是 JAVA的基本类型 , 所以在你客户端调用的时候你需要注册一下,如: QNameqn=newnewnewnewQName("urn:AddressManager","Address"); QNameqn1=newnewnewnewQName("urn:AddressInnerClass","myNSD:InnerClass"); call.registerTypeMapping(Address.classclassclassclass,qn, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); call.registerTypeMapping(Address.InnerClass.classclassclassclass,qn1, BeanSerializerFactory.classclassclassclass,BeanDeserializerFactory.classclassclassclass); 大家在这里看见的写法和上面的写法有点区别,其实这是一个简易写法,所表达的意思是相 同的,都是表示这个类可以序列化和反序列化。 最后就是关于 WSDD 的部署代码如下: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第54页 共207 页 这里可以看书 Address 里的内部类也需要做映射。 运行结果: 客户端: Listsize:2 id号:1address:Haidiancity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:1list:[1,2,3]isExist:false innerClass.name:MyInnername id号:2address:Chaoyangcity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:Alist:[1,2,3]isExist:true innerClass.name:MyInnername Mapsize:2 id号:1address:Haidiancity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:1list:[1,2,3]isExist:false innerClass.name:MyInnername id号:2address:Chaoyangcity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:Alist:[1,2,3]isExist:true innerClass.name:MyInnername Listsize:2 id号:1address:Haidiancity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:1list:[1,2,3]isExist:false innerClass.name:MyInnername id号:2address:Chaoyangcity:BeiJingcountry:ChinapostalCode:100081 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第55页 共207 页 province:Beijingarray:Alist:[1,2,3]isExist:true innerClass.name:MyInnername Mapsize:2 id号:1address:Haidiancity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:1list:[1,2,3]isExist:false innerClass.name:MyInnername id号:2address:Chaoyangcity:BeiJingcountry:ChinapostalCode:100081 province:Beijingarray:Alist:[1,2,3]isExist:true innerClass.name:MyInnername 2.2.5.32.2.5.32.2.5.32.2.5.3 RMI RMI RMI RMI 方式远程调用方式远程调用方式远程调用方式远程调用 到目前为止所有例子都是先提供一个类然后在给出对应的实现,下面介绍一种类似 RMI 的实现例子给大家参考,来看代码: 提供服务的接口: Java 代码: packagepackagepackagepackagewebservice.axis.wsdd; /** *本地实现一个Remote接口,其中包含远程WS的方法(同名、同返回类型、同参数类型), *则通过Service可以获得一个对远程WS对象的引用。用该引用可以直接像调用本地方法一样 调用远程方法。 *服务端不用做任何设置和调整。 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-14 */ publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceIHelloWorldWSDDextendsextendsextendsextendsjava.rmi.Remote{ publicpublicpublicpublicStringhello(Stringname); publicpublicpublicpublicFloatadd(Floata,floatfloatfloatfloatb); } WebService 服务端: Java 代码: packagepackagepackagepackagewebservice.axis.wsdd; publicpublicpublicpublicclassclassclassclassHelloWorldWSDD{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第56页 共207 页 privateprivateprivateprivateintintintintrequestCount=0; publicpublicpublicpublicStringhello(Stringname){ requestCount++; System.out.println("requestCount="+requestCount); System.out.println("Received:"+name); returnreturnreturnreturn"Hello"+name; } publicpublicpublicpublicFloatadd(Floata,floatfloatfloatfloatb){ requestCount++; Stringresult="a="+a+",b="+b; System.out.println("requestCount="+requestCount); System.out.println("Received:"+result); returnreturnreturnreturna+b; } } 通过上面的代码可以看出服务端和之前我们写的代码是一样的,没有任何变化。客户端接口 提供方法和参数完全和服务端提供的一样,这样你可以根据接口的方法来操作服务端的方法 (服务端不需要实现这个接口,这个接口对服务端是透明的)。这样可以给你带来更方便的 开发,当你要提供 WebService 服务的时候你可以不用修改你的服务端代码直接以接口形式 提供就可以了。 客户端的实现: Java 代码: packagepackagepackagepackagewebservice.axis.wsdd; importimportimportimportjava.rmi.RemoteException; importimportimportimportjavax.xml.namespace.QName; importimportimportimportjavax.xml.rpc.ServiceException; importimportimportimportorg.apache.axis.client.Call; importimportimportimportorg.apache.axis.client.Service; publicpublicpublicpublicclassclassclassclassClientWSDD{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ trytrytrytry{ Stringurl= Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第57页 共207 页 "http://127.0.0.1:8080/myaxis/services/HelloWorldWSDD"; Serviceserv=newnewnewnewService(); Callcall=(Call)serv.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(newnewnewnewQName(url,"hello")); //Stringresult=(String)call.invoke(new Object[]{"Quhailong"}); //System.out.println("result="+result); IHelloWorldWSDDremoteRef=(IHelloWorldWSDD) serv.getPort(url,IHelloWorldWSDD.classclassclassclass); Stringresult=remoteRef.hello("Quhailong"); System.out.println("result="+result); result=remoteRef.hello("Quhailong"); System.out.println("result="+result); call.setOperationName(newnewnewnewQName(url,"add")); FloatreturnValue=(Float)call.invoke(newnewnewnewObject[]{newnewnewnew Float(3.2),newnewnewnewFloat(2.8)}); System.out.println("returnValue="+returnValue); }catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); }catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } } WSDD 代码: 在这里顺便提一下如果要是 HelloWorldWSDD 只想暴露 2个方法而不是全部,可以使用 这样来达到效果(其 中方法 1&2 是用英文的逗号隔开的)。 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第58页 共207 页 2.2.62.2.62.2.62.2.6 抛出异常 上一篇介绍了如果在Server 和Client端传递一个自己的对象。有些人也许会问传递异 常行不行?答案是可以。只不过传递异常的配置要稍微复杂一些。下面我用代码来说明下: 服务端的异常类: Java代码: packagepackagepackagepackagewebservice.axis.wsddexception; importimportimportimportjava.rmi.RemoteException; /** *服务器端的异常 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassServerExceptionextendsextendsextendsextendsRemoteException{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=- 8703656417727568771L; privateprivateprivateprivateStringerrMSG=""; publicpublicpublicpublicServerException(){ System.out.println("ServerException!"); } publicpublicpublicpublicvoidvoidvoidvoidprintErrorDescription(){ System.out.println(errMSG); } publicpublicpublicpublicStringgetErrMSG(){ returnreturnreturnreturnerrMSG; } publicpublicpublicpublicvoidvoidvoidvoidsetErrMSG(StringerrMSG){ thisthisthisthis.errMSG=errMSG; } } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第59页 共207 页 提供的WebService代码: Java代码 packagepackagepackagepackagewebservice.axis.wsddexception; /** *产生异常的方法测试 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassExceptionCreater{ publicpublicpublicpublicvoidvoidvoidvoidgetException()throwsthrowsthrowsthrowsServerException{ ServerExceptionse=newnewnewnewServerException(); se.setErrMSG("ServerSideSelfException!"); throwthrowthrowthrowse; } } 客户端的异常: Java代码: packagepackagepackagepackagewebservice.axis.wsddexception; importimportimportimportjava.rmi.RemoteException; /** *客户器端的异常 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassClientExceptionextendsextendsextendsextendsRemoteException{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=- 8703656417727568771L; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第60页 共207 页 privateprivateprivateprivateStringerrMSG="ClientSideSelfException!"; publicpublicpublicpublicClientException(){ System.out.println("ClientException!"); } publicpublicpublicpublicvoidvoidvoidvoidprintErrorDescription(){ System.out.println(errMSG); } publicpublicpublicpublicStringgetErrMSG(){ returnreturnreturnreturnerrMSG; } publicpublicpublicpublicvoidvoidvoidvoidsetErrMSG(StringerrMSG){ thisthisthisthis.errMSG=errMSG; } } 客户端代码 Java 代码: packagepackagepackagepackagewebservice.axis.wsddexception; importimportimportimportjava.rmi.RemoteException; importimportimportimportjavax.xml.namespace.QName; importimportimportimportjavax.xml.rpc.ServiceException; importimportimportimportorg.apache.axis.client.Call; importimportimportimportorg.apache.axis.client.Service; /** *获得WebService的返回异常的客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassClientExceptionReceiver{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ trytrytrytry{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第61页 共207 页 Stringurl= "http://127.0.0.1:8080/myaxis/services/ExceptionCreater"; Serviceserv=newnewnewnewService(); Callcall=(Call)serv.createCall(); QNameqn=newnewnewnewQName("urn:CustomerFault", "ServerException"); call.registerTypeMapping(ClientException.classclassclassclass,qn, newnewnewnew org.apache.axis.encoding.ser.BeanSerializerFactory( ClientException.classclassclassclass,qn), newnewnewnew org.apache.axis.encoding.ser.BeanDeserializerFactory( ClientException.classclassclassclass,qn)); call.setTargetEndpointAddress(url); Object[]param=nullnullnullnull; call.setOperationName(newnewnewnewQName(url,"getException")); System.out.println("WillCatchException"); Stringresult=(String)call.invoke(param); System.out.println("result="+result); }catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); }catchcatchcatchcatch(ClientExceptione){ System.out.println("CatchException"); e.printErrorDescription(); e.printStackTrace(); }catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } } } WSDD 的文件描述: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第62页 共207 页 首先不同的是多了个命名空间也就是namespace节点,等会测试代码中会看到用途。除了 namespace之外还有operation这个节点和里面的fault子节点。先来介绍operation这个节点 的属性。 � name:操作名称或者方法名称,这个值会和你server发布的相关方法名匹配,所以要和 方法名相同。 � qname:针对这个operation的限定名。 � xmlns:针对这个qname 的命名空间也就是namespace。 � Fault:节点代表要这个方法要抛出的异常。 � namenamenamename:随便起的名字。 � type="tns:ServerException"type="tns:ServerException"type="tns:ServerException"type="tns:ServerException"::这里的一定要写出你要抛出的异常的类型。 运行结果: 客户端: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第63页 共207 页 WillCatchException ClientException! CatchException ServerSideSelfException! webservice.axis.wsddexception.ClientException atsun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) atsun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) atjava.lang.reflect.Constructor.newInstance(UnknownSource) atjava.lang.Class.newInstance0(UnknownSource) atjava.lang.Class.newInstance(UnknownSource) at org.apache.axis.encoding.ser.BeanDeserializer.(BeanDeserializer .java:104) at org.apache.axis.encoding.ser.BeanDeserializerFactory.getGeneralPurpos e(BeanDeserializerFactory.java:89) at org.apache.axis.encoding.ser.BaseDeserializerFactory.getDeserializerA s(BaseDeserializerFactory.java:89) at org.apache.axis.encoding.DeserializationContext.getDeserializer(Deser ializationContext.java:464) at org.apache.axis.encoding.DeserializationContext.getDeserializerForTyp e(DeserializationContext.java:547) at org.apache.axis.message.SOAPFaultDetailsBuilder.onStartChild(SOAPFaul tDetailsBuilder.java:157) at org.apache.axis.encoding.DeserializationContext.startElement(Deserial izationContext.java:1035) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startEle ment(UnknownSource) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scan StartElement(UnknownSource) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImp Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第64页 共207 页 l$FragmentContentDriver.next(UnknownSource) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(U nknownSource) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next (UnknownSource) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImp l.scanDocument(UnknownSource) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(U nknownSource) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(U nknownSource) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Un knownSource) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.p arse(UnknownSource) atjavax.xml.parsers.SAXParser.parse(UnknownSource) at org.apache.axis.encoding.DeserializationContext.parse(Deserialization Context.java:227) atorg.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696) atorg.apache.axis.Message.getSOAPEnvelope(Message.java:435) at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnders tandChecker.java:62) atorg.apache.axis.client.AxisClient.invoke(AxisClient.java:206) atorg.apache.axis.client.Call.invokeEngine(Call.java:2784) atorg.apache.axis.client.Call.invoke(Call.java:2767) atorg.apache.axis.client.Call.invoke(Call.java:2443) atorg.apache.axis.client.Call.invoke(Call.java:2366) atorg.apache.axis.client.Call.invoke(Call.java:1812) at webservice.axis.wsddexception.ClientExceptionReceiver.main(ClientExce ptionReceiver.java:54) Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第65页 共207 页 服务端: Server Exception! 2.2.72.2.72.2.72.2.7 传递文件 服务端 Java 代码: packagepackagepackagepackagewebservice.axis.wsddfiletranspot; importimportimportimportjava.io.File; importimportimportimportjava.io.FileOutputStream; importimportimportimportjava.io.IOException; importimportimportimportjava.io.InputStream; importimportimportimportjavax.activation.DataHandler; /** *接收文件的服务端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassFileReceiverServer{ publicpublicpublicpublicStringreceive(DataHandlerhandler,StringfileName){ Filefile=newnewnewnewFile(fileName); ifififif(handler==nullnullnullnull||fileName==nullnullnullnull||fileName.equals("")) { returnreturnreturnreturn"failure"; } InputStreaminput=nullnullnullnull; FileOutputStreamfos=nullnullnullnull; trytrytrytry{ input=handler.getInputStream(); fos=newnewnewnewFileOutputStream(file); bytebytebytebyte[]buffer=newnewnewnewbytebytebytebyte[1024]; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第66页 共207 页 whilewhilewhilewhile(input.read(buffer)!=-1){ fos.write(buffer); } }catchcatchcatchcatch(IOExceptione){ e.printStackTrace(); }finallyfinallyfinallyfinally{ ifififif(input!=nullnullnullnull){ trytrytrytry{ input.close(); }catchcatchcatchcatch(IOExceptione){ e.printStackTrace(); } } ifififif(fos!=nullnullnullnull){ trytrytrytry{ fos.close(); }catchcatchcatchcatch(IOExceptione){ e.printStackTrace(); } } } returnreturnreturnreturn"Successfilesavedonserver.At:"+ file.getAbsolutePath(); } } 在这个服务端代码里我们主要介绍一个类就是 DataHandler 其实这个类是一个专门的传送 器,通过他可以把文件进行序列化。这个方法从 DataHandler 得到一个输入流,从这个流里 读出数据然后写到一个新文件里。这些都是一些基本的 Java I/O 操作。 在这个地方有必要说一下就是大家在以前看见的地方都是用 beanMapping 来配置的,其实用 typeMapping 也是一样的,这里就不多说了。我主要说一下就是关于 org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory 和 org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory 其实这两个类也是很简单的,因为我们要序列化不同的对象所以我们要用到不同的工厂类, 同样当你要序列化文件的时候也要用到文件的工厂类。 最后来让我们看看客户端的代码实现: Java 代码: importimportimportimportjava.rmi.RemoteException; importimportimportimportjavax.activation.DataHandler; importimportimportimportjavax.activation.FileDataSource; importimportimportimportjavax.xml.namespace.QName; importimportimportimportjavax.xml.rpc.ParameterMode; importimportimportimportjavax.xml.rpc.ServiceException; importimportimportimportjavax.xml.rpc.encoding.XMLType; importimportimportimportorg.apache.axis.client.Call; importimportimportimportorg.apache.axis.client.Service; importimportimportimportorg.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory; importimportimportimportorg.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第68页 共207 页 /** *传输文件的客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassFileSenderClient{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ trytrytrytry{ StringfileName="readme.txt"; DataHandlerdh=newnewnewnewDataHandler(newnewnewnew FileDataSource(FileSenderClient.classclassclassclass.getResource(fileName).getPath()) ); Stringurl= "http://127.0.0.1:8080/myaxis/services/FileReceiverServer"; Serviceserv=newnewnewnewService(); Callcall=(Call)serv.createCall(); call.setTargetEndpointAddress(url); call.setOperationName(newnewnewnewQName(url,"receive")); QNameqn=newnewnewnewQName("DataHandler","myNs:DataHandler"); call.registerTypeMapping(DataHandler.classclassclassclass,qn, JAFDataHandlerSerializerFactory.classclassclassclass, JAFDataHandlerDeserializerFactory.classclassclassclass); call.addParameter("s1",qn,ParameterMode.IN); call.addParameter("s2",XMLType.XSD_STRING, ParameterMode.IN); call.setReturnClass(String.classclassclassclass); StringreturnStr=(String)call.invoke(newnewnewnewObject[]{dh, "server.txt"}); System.out.println("Serverresponse:"+returnStr); }catchcatchcatchcatch(ServiceExceptione){ e.printStackTrace(); }catchcatchcatchcatch(RemoteExceptione){ e.printStackTrace(); } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第69页 共207 页 } } 然后进行测试。 输出结果: 客户端: Serverresponse:Successfilesavedonserver.At: D:\Tomcat\bin\server.txt 上面的列子都是经过测试而且完全跑通的,我们希望大家能够自己动手完成这些列子提 高自己的水平。在下一章我们将会简单介绍一下关于 AXIS 的调试工具和相关的命令使用。 2.3.AXIS 2.3.AXIS 2.3.AXIS 2.3.AXIS 的常用的命令和调试工具的使用的常用的命令和调试工具的使用的常用的命令和调试工具的使用的常用的命令和调试工具的使用 2.3.12.3.12.3.12.3.1 AXIS AXIS AXIS AXIS 的常用命令: 部署你的WSDD 的命令是到 AXIS 的web-inf 下然后运行 java org.apache.axis.client.AdminClient 你的部署文件。例如: java org.apache.axis.client.AdminClient e:\deploy.wsdd 上面的部署只是简单的部署,其实关于 AdminClient 有很多参数命令,感兴趣的朋友可以自 己看看只要在 AdminClient -help 就可以看到相关的参数命令。在这里我们主要讲解 2个重 要的和比较常用的,-l和-p一般有的时候我们不是使用 8080 这个端口,但是当你部署的时 候你没有指定端口这样 AXIS 会默认使用 8080 所以就会导致部署失败,遇见这种情况就要 使用参数-p来解决。 例如:你的 TOMCAT 使用的是 8089 端口,当你部署的时候要如下代码: java org.apache.axis.client.AdminClient e:\deploy.wsdd -p8089 注意:-p后面直接加端口。 还有一种就是关于-l 的使用,由于AXIS 默认部署的时候使用的虚拟路径是 axis,但是 有的人不喜欢这个虚拟路径往往在 TOMCAT 里面就修改 server.xml 文件,创建自己的服务这 个时候当你部署的时候你就需要使用-l 命令了,例如你的虚拟路径是 myaxis 那么你在部署 的时候就要如下代码: java org.apache.axis.client.AdminClient e:\deploy.wsdd -lhttp://127.0.0.1:8080/myaxis/services/AdminService Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第70页 共207 页 2.3.22.3.22.3.22.3.2 调试工具的使用 关于调试工具的使用在这里我简单的说明一下,代码如下: 运行java org.apache.axis.utils.tcpmon就会出现调试工具如图: 这样你就可以填写本地的地址和端口,还有你要监听的端口(提示:这里说下就是关于监听 的用法,在监听了写上你要啊监控的端口号例如:8081 那么你在提供给客户端的URL的时 候就要写上这个端口号,而不是服务端的端口号。例如:127.0.0.1:8081 因为这个是你的 请求发送到这个工具上然后这个工具又发送到你真正的服务端上。) 然后点Add这样你就可以看到一些传递的详细信息了,如图: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第71页 共207 页 2.4.Axis 2.4.Axis 2.4.Axis 2.4.Axis 通过 通过 通过 通过 WSDL WSDL WSDL WSDL 生成服务端代码生成服务端代码生成服务端代码生成服务端代码 一般情况下我们使用 Web 服务都是通过服务端提供 WSDL 信息来生成客户端的调用框架, 但也不尽然,比如说通讯双方先定义好协议,也就是说最新确定下来的是 WSDL,就比如 说移动的飞信平台,我们从移动获取到的 wsdl 的文件,现在必须依照 wsdl 文件来生成服务 端的实现框架,也就是说我们是作为 web 服务的服务端来给飞信平台调用。做法如下: java -Djava.ext.dirs={axis-lib} org.apache.axis.wsdl.WSDL2Java --server-side dsmp.wsdl 通过上面的命令帮你生成了服务端代码: 然后在代码里以 BindingImpl 结尾是 Web 服务的方法实现,你剩下的所有代码都可以在里面 进行添加和修改。 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第72页 共207 页 2.5 Axis1.4 读取头信息 在Axis 里读取头的信息是通过 Handler 来读取的本身它提供很多这样类似拦截的类有日志, JWS,SOAPMonitor,JAXRPC 等在这里我们只介绍 JAXRPCHandler 使用。 假设你的头信息如下: SubscribeService 090204095129 1.0.0 000 210001 000 100000 000 210001 20090204095129 以上是定义好的头信息 假设客户端已经把这个头信息已经写入了,现在我们要用 AXIS 来 读取这个头信息,来看代码实现: /* *文件名: TestSOAPMonitorService.java * *创建日期: 2009-2-13 * *Copyright(C)2009,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagecom.chinamobile.www.vgop.serviceorder.v1_0; importimportimportimportjava.util.Iterator; importimportimportimportjava.util.List; importimportimportimportjavax.xml.soap.SOAPException; importimportimportimportjavax.xml.soap.SOAPHeader; importimportimportimportorg.apache.axis.MessageContext; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第73页 共207 页 importimportimportimportorg.apache.axis.handlers.JAXRPCHandler; importimportimportimportorg.apache.axis.message.MessageElement; importimportimportimportorg.apache.axis.message.NodeImpl; importimportimportimportorg.apache.axis.message.SOAPHeaderElement; importimportimportimportorg.apache.axis.message.Text; /** * * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2009-2-13 */ publicpublicpublicpublicclassclassclassclassTestSOAPMonitorServiceextendsextendsextendsextendsJAXRPCHandler{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=4754889674831614631L; @SuppressWarnings("unchecked") publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextmsgContext){ trytrytrytry{ //获取头的对象 SOAPHeaderheader= msgContext.getCurrentMessage().getSOAPHeader(); //获取头的子节点 forforforfor(Iteratorit=header.getChildElements();it.hasNext();){ SOAPHeaderElementelement=(SOAPHeaderElement)it.next(); //获取每个节点的子节点 Listlist=element.getChildren(); forforforfor(intintintinti=0;i 这个配置要放到你的 service这个节点里面,由于部分代码涉及到公司机密所以在这里我就不 给贴出来的这 2个地方都写好了 就可以部署你的 deploy.wsdd了。然后运行你的客户端这个 是否服务端就会打印一下结果: 节点名字:msgName节点值:SubscribeService 节点名字:transactionID节点值:090204095129 节点名字:version节点值:1.0.0 父节点名字:sendAddress节点名字:provType节点值:000 父节点名字:sendAddress节点名字:platType节点值:210001 父节点名字:destAddress节点名字:provType节点值:000 父节点名字:destAddress节点名字:platType节点值:100000 父节点名字:originalAddress节点名字:provType节点值:000 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第75页 共207 页 父节点名字:originalAddress节点名字:platType节点值:210001 节点名字:timeStamp节点值:20090204095129 2.6 .NET访问 AXIS 的出现 Client.NoSOAPAction 的解决方 案 这个问题是由于在.NET 访问的时候缺少了 SOAPAction,但是由于 AXIS 里又对 SOAPAction 做了校验所有会出现上面的问题,解决办法就是自己继承 AxisServlet 这个类然后进行重写 里面的 getSoapAction 方法。 /** *ExtracttheSOAPActionheader.ifSOAPActionisnullthen we'llwebe *forcedtoscanthebodyforit.ifSOAPActionis""then usetheURL * *@param@param@param@paramreq * incomingrequest *@return@return@return@returntheaction *@throws@throws@throws@throwsAxisFault */ privateprivateprivateprivateStringgetSoapAction(HttpServletRequestreq)throwsthrowsthrowsthrows AxisFault{ returnreturnreturnreturn req.getContextPath(); } 这样就可以了。然后在配置XML的时候使用你自己实现的类。例如我们这里是MyAxisServlet 在写应用的时候就要写 AxisServlet Apache-Axis Servlet com.chinamobile.MyAxisServlet 2.7 AXIS 服务端返回 SOAP Header 给客户端 一般的时候都是客户端想服务端传送头信息,然后服务端在处理请求后在把头返回给客户 端。我在项目里就涉及到了这方面的应用,我记录下来和大家分享一下。 假设你已经写好了客户端并且头的信息是: syncOrderRelationReq 13637 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第76页 共207 页 1.0.0 000 100000 000 210001 000 106000 20090217203710 现在我们用 AXIS 来做响应,然后在返回给客户端的时候也是带有这个头信息的。 请看下面的代码: /* *文件名: TestSOAPMonitorService.java * *创建日期: 2009-2-13 * *Copyright(C)2009,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagecom.chinamobile.www.vgop.serviceorder.v1_0; importimportimportimportjava.util.Iterator; importimportimportimportorg.apache.axis.message.SOAPEnvelope; importimportimportimportjavax.xml.soap.SOAPHeader; importimportimportimportorg.apache.axis.Message; importimportimportimportorg.apache.axis.MessageContext; importimportimportimportorg.apache.axis.handlers.BasicHandler; importimportimportimportorg.apache.axis.message.SOAPBody; importimportimportimportorg.apache.axis.message.SOAPHeaderElement; /** * * *@author@author@author@authorxiaozhi Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第77页 共207 页 * *@version@version@version@version$Revision$ * *@since@since@since@since2009-2-13 */ publicpublicpublicpublicclassclassclassclassTestSOAPMonitorServiceextendsextendsextendsextendsBasicHandler{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID= 4754889674831614631L; privateprivateprivateprivateMessageimsg,omsg; privateprivateprivateprivateSOAPEnvelopeienvelope,oenvelope; privateprivateprivateprivateSOAPHeaderiheader,oheader; privateprivateprivateprivateSOAPBodyibody,obody; publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextmsgContext){ trytrytrytry{ Messagemessage=msgContext.getCurrentMessage(); SOAPEnvelopeenv=message.getSOAPEnvelope(); //读取请求信息和获取请求头的对象 imsg=msgContext.getRequestMessage(); SOAPEnvelopeienvelope=imsg.getSOAPEnvelope(); iheader=(SOAPHeader)ienvelope.getHeader(); //响应信息和响应的头对象 omsg=msgContext.getResponseMessage(); SOAPEnvelopeoenvelope=omsg.getSOAPEnvelope(); oheader=(SOAPHeader)oenvelope.getHeader(); forforforfor(Iteratoriter=iheader.examineAllHeaderElements() ;iter.hasNext();){ SOAPHeaderElementhel=(SOAPHeaderElement) iter.next(); //将获取请求的头方法哦响应信息的头里 oheader.addChildElement(hel); StringheaderName=hel.getNodeName(); } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第78页 共207 页 msgContext.setResponseMessage(omsg); System.out.println("header==="+env.getHeader()); } catchcatchcatchcatch(Exceptione){ //TODOTODOTODOTODOAuto-generatedcatchblock e.printStackTrace(); } } } 通过以上代码相信不用做过多介绍大家就可以理解了 ,但是代码写完了还要在部署描述符 里进行响应的配置, 这样打开你的 TCPMON就可以监控到服务端返回给客户端的信息里也有 header消息了。 3.3.3.3. XFie 篇 3.13.13.13.1 XFire XFire XFire XFire 的简介的简介的简介的简介 XFire 是下一代的 java SOAP 框架。XFire 提供了非常方便的 API,使用这些 API 可以 开发面向服务(SOA)的程序。它支持各种标准,性能优良(基于低内存的 STAX 模 型 )。 � 支持多个重要的 Web Service 标准,包括 SOAP 、WSDL、WS-I Basic Profile 、 WSAddressing、WS-Security 等。 � 高性能的 SOAP 栈。 � 可选的绑定(binding)方式,如POJO、XMLBeansJAXB1.1、JAXB2.0、Castor 和JiBX 等 。 � 支持 JSR181 API。 � 多种传输方式,如 HTTP、JMS、XMPP、In-JVM 等。 � 灵活的接口。 � 支持多个容器,如 Spring、Pico、Plexus、Loom。 � 支持 JBI,参看 servicemix 项目(http://servicemix.org)。 � 客户端和服务器代码生成。 在开发之前对用到的软件版本说明一下,因为不同的版本有些区别。我们这里所用的是 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第79页 共207 页 目前最新的版本。xfire-1.2.6。在这里说明一下:由于 JDK 版本的不同加载包的时候也会有 所不同,我们是基于 1.5 以上做的所以加载包如下:activation-1.1.jar,commons-codec-1.3.jar, commons-httpclient-3.0.jar,commons-logging-1.0.4.jar,jaxb-api-2.0.jar,jaxb-impl-2.0.1.jar, jaxen-1.1-beta-9.jar,jdom-1.0.jar,jsr173_api-1.0.jar,mail-1.4.jar,spring.jar(这里的是 2.0 以 上 的 包 ),stax-api-1.0.1.jar,wsdl4j-1.6.1.jar,wss4j-1.5.1.jar,wstx-asl-3.2.6.jar,xbean-2.2.0.jar, xbean-spring-2.8.jar,xfire-all-1.2.6.jar,xfire-jsr181-api-1.0-M1.jar,XmlSchema-1.1.jar, xmlsec-1.3.0.jar。 在你的 Web.xml 里的配置如下: XFireServlet org.codehaus.xfire.transport.http.XFireConfigurableServlet 0 XFireServlet /servlet/XFireServlet/* XFireServlet /services/* 做完以上工作我们就可以开始我的 XFire之旅了。 3.23.23.23.2 简单的应用 废话少说直接看代码: WebService 的接口: /* *文件名: IHelloWorld.java * *创建日期: 2008-7-14 * *Copyright(C)2008,byAlong. * *原始作者:Along * Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第80页 共207 页 */ packagepackagepackagepackagewebservice.xfire.simple; /** *本地实现一个Remote接口,其中包含远程WS的方法(同名、同返回类型、同参数类型), *则通过Service可以获得一个对远程WS对象的引用。用该引用可以直接像调用本地方法一样调用远程 方法。 *服务端不用做任何设置和调整。 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-14 */ publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceIHelloWorldextendsextendsextendsextendsjava.rmi.Remote{ publicpublicpublicpublicStringhello(Stringname); publicpublicpublicpublicFloatadd(Floata,floatfloatfloatfloatb); } 服务端: Java 代码: /* *文件名: HelloWorld.java * *创建日期: 2008-7-23 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.simple; /** *简单的Service实现 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-23 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第81页 共207 页 */ publicpublicpublicpublicclassclassclassclassHelloWorld{ privateprivateprivateprivateintintintintrequestCount=0; publicpublicpublicpublicStringhello(Stringname){ requestCount++; System.out.println("requestCount="+requestCount); System.out.println("Received:"+name); returnreturnreturnreturn"Hello"+name; } publicpublicpublicpublicFloatadd(Floata,floatfloatfloatfloatb){ requestCount++; Stringresult="a="+a+",b="+b; System.out.println("requestCount="+requestCount); System.out.println("Received:"+result); returnreturnreturnreturna+b; } } 客户端调用: Java 代码: /* *文件名: Client.java * *创建日期: 2008-7-23 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.simple; importimportimportimportjava.net.MalformedURLException; importimportimportimportorg.codehaus.xfire.client.XFireProxyFactory; importimportimportimportorg.codehaus.xfire.service.Service; importimportimportimportorg.codehaus.xfire.service.binding.ObjectServiceFactory; /** Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第82页 共207 页 *XFire客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-23 */ publicpublicpublicpublicclassclassclassclassClient{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ Stringurl= "http://127.0.0.1:8080/myxfire/services/HelloWorldSimple"; ServiceserviceModel=newnewnewnew ObjectServiceFactory().create(IHelloWorld.classclassclassclass); trytrytrytry{ IHelloWorldservice=(IHelloWorld)newnewnewnew XFireProxyFactory().create(serviceModel,url); Stringresult=service.hello(System.getProperty("user.name")); System.out.println("result="+result); FloatreturnValue=service.add(newnewnewnewFloat(3.2),newnewnewnewFloat(2.8)); System.out.println("returnValue="+returnValue); }catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } } } 以上是对应的代码实现,现在开始编写我们的部署文件:首先在你的 src 下创建 META- INF/xfire 文件在下面创建 services.xml。现在介绍一下里面的配置方式, HelloWorldSimple http://simple.xfire.webservice/HelloWorld webservice.xfire.simple.HelloWorld Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第83页 共207 页 webservice.xfire.simple.HelloWorld request 在这里说明一下上面的配置文件的意思:首先强调一点就是关于 xmlns=http://xfire.codehaus.org/config/1.0的写法,由于上面的是和 Spring2.0 做的结合这样就要把上面的这句话加到你的 service里面。如果是和 1.X版本结合那么就要把 这句话加到你的 beans后面。 service:包含你要生命的服务。 name:表示你的服务名字。 namesace:表示你的命名空间。 serviceClass: 提供服务的类一般是接口,也可以是具体的实现类。 implementationClass:对应接口的实现。 scope:存活的范围。 以上工作都做好了现在可以进行你的测试了,发布你的服务然后运行客户端程序如果输出: result=HelloAdministrator returnValue=6.0 表示你已经成功了。 3.33.33.33.3 传递复杂对象 3333.3.1.3.1.3.1.3.1 List、Map、数组和自定义对象 3.3.1.13.3.1.13.3.1.13.3.1.1 在对象里包含的 List,Map,数组 自定义的 JAVA对象: /* *文件名: Address.java * *创建日期: 2008-7-11 * *Copyright(C)2008,byAlong. * *原始作者:Along * Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第84页 共207 页 */ packagepackagepackagepackagewebservice.xfire.selfobj.server.model; importimportimportimportjava.io.Serializable; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.List; importimportimportimportjava.util.Map; /** *服务端的自定义类型 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassAddressimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=5182870829593983607L; privateprivateprivateprivateIntegeridentifier; /**地址 */ privateprivateprivateprivateStringaddress; /**城市 */ privateprivateprivateprivateStringcity; /**省份 */ privateprivateprivateprivateStringprovince; /**国家 */ privateprivateprivateprivateStringcountry; /**邮编 */ privateprivateprivateprivateStringpostalCode; privateprivateprivateprivateString[]array; privateprivateprivateprivateListlist; privateprivateprivateprivateMapmap; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第85页 共207 页 privateprivateprivateprivatebooleanbooleanbooleanbooleanisExist; privateprivateprivateprivateInnerClassinnC; publicpublicpublicpublicstaticstaticstaticstaticclassclassclassclassInnerClassimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=-2330738090948448510L; privateprivateprivateprivateStringinnerName="staticInnerClass"; publicpublicpublicpublicInnerClass(){}; publicpublicpublicpublicInnerClass(StringinnerName){ supersupersupersuper(); thisthisthisthis.innerName=innerName; } publicpublicpublicpublicStringgetInnerName(){ returnreturnreturnreturninnerName; } publicpublicpublicpublicvoidvoidvoidvoidsetInnerName(StringinnerName){ thisthisthisthis.innerName=innerName; } } publicpublicpublicpublicAddress(){ list=newnewnewnewArrayList(); list.add(1); list.add(2); list.add(3); map=newnewnewnewHashMap(); map.put(1,newnewnewnewInnerClass("A")); map.put(2,newnewnewnewInnerClass("B")); map.put(3,newnewnewnewInnerClass("C")); innC=newnewnewnewInnerClass(); innC.setInnerName("服务端:Address.InnerClass"); } @Override Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第86页 共207 页 publicpublicpublicpublicStringtoString(){ StringreturnStr=supersupersupersuper.toString() +"id号:"+getIdentifier() +"address:"+getAddress() +"city:"+getCity() +"country:"+getCountry() +"postalCode:"+getPostalCode() +"province:"+getProvince() +"array:"+getArray()[0] +"list:"+getList() +"map:"+getMap() +"isExist:"+isExist() +"innerClass.name:"+getInnC().getInnerName(); returnreturnreturnreturnreturnStr; } publicpublicpublicpublicInnerClassgetInnC(){ returnreturnreturnreturninnC; } publicpublicpublicpublicvoidvoidvoidvoidsetInnC(InnerClassinnC){ thisthisthisthis.innC=innC; } publicpublicpublicpublicIntegergetIdentifier(){ returnreturnreturnreturnidentifier; } publicpublicpublicpublicvoidvoidvoidvoidsetIdentifier(Integeridentifier){ thisthisthisthis.identifier=identifier; } publicpublicpublicpublicStringgetAddress(){ returnreturnreturnreturnaddress; } publicpublicpublicpublicvoidvoidvoidvoidsetAddress(Stringaddress){ thisthisthisthis.address=address; } publicpublicpublicpublicStringgetCity(){ returnreturnreturnreturncity; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第87页 共207 页 publicpublicpublicpublic voidvoidvoidvoid setCity(String city) { thisthisthisthis.city = city; } publicpublicpublicpublic String getProvince() { returnreturnreturnreturn province; } publicpublicpublicpublic voidvoidvoidvoid setProvince(String province) { thisthisthisthis.province = province; } publicpublicpublicpublic String getCountry() { returnreturnreturnreturn country; } publicpublicpublicpublic voidvoidvoidvoid setCountry(String country) { thisthisthisthis.country = country; } publicpublicpublicpublic String getPostalCode() { returnreturnreturnreturn postalCode; } publicpublicpublicpublic voidvoidvoidvoid setPostalCode(String postalCode) { thisthisthisthis.postalCode = postalCode; } publicpublicpublicpublic String[] getArray() { returnreturnreturnreturn array; } publicpublicpublicpublic voidvoidvoidvoid setArray(String[] array) { thisthisthisthis.array = array; } publicpublicpublicpublic booleanbooleanbooleanboolean isExist() { returnreturnreturnreturn isExist; } publicpublicpublicpublic voidvoidvoidvoid setExist(booleanbooleanbooleanboolean isExist) { thisthisthisthis.isExist = isExist; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第88页 共207 页 publicpublicpublicpublicListgetList(){ returnreturnreturnreturnlist; } publicpublicpublicpublicvoidvoidvoidvoidsetList(Listlist){ thisthisthisthis.list=list; } publicpublicpublicpublicMapgetMap(){ returnreturnreturnreturnmap; } publicpublicpublicpublicvoidvoidvoidvoidsetMap(Mapmap){ thisthisthisthis.map=map; } } 从上面的对象里可以看到我们自定义的对象里包括了:List,Map 和内部类。 服务端代码: /* *文件名: AddressManager.java * *创建日期: 2008-7-11 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.selfobj.server; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.List; importimportimportimportwebservice.xfire.selfobj.server.model.Address; /** *提供复杂对象的WebService业务 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第89页 共207 页 * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassAddressManager{ privateprivateprivateprivateintintintintrequestCount=0; publicpublicpublicpublicList
getAddressList(){ requestCount++; System.out.println("requestCount="+requestCount); List
returnList=newnewnewnewArrayList
(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); returnList.add(address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); returnList.add(address); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); returnreturnreturnreturnreturnList; } publicpublicpublicpublicList
setAddressList(List
list){ requestCount++; System.out.println("requestCount="+requestCount); returnreturnreturnreturnlist; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第90页 共207 页 } 客户端接口: Java 代码: /* *文件名: IClientAddressManager.java * *创建日期: 2008-7-17 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.selfobj.client; importimportimportimportjava.util.List; importimportimportimportwebservice.xfire.selfobj.server.model.Address; /** *本地实现一个Remote接口,其中包含远程WS的方法(同名、同返回类型、同参数类型), *则通过Service可以获得一个对远程WS对象的引用。用该引用可以直接像调用本地方法一样调用远程 方法。 *服务端不用做任何设置和调整。 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-17 */ publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceIClientAddressManager{ publicpublicpublicpublicList
getAddressList(); publicpublicpublicpublicList
setAddressList(List
list); } 客户端: Java 代码: /* *文件名: Client.java Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第91页 共207 页 * *创建日期: 2008-7-23 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.selfobj.client; importimportimportimportjava.net.MalformedURLException; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.Iterator; importimportimportimportjava.util.List; importimportimportimportorg.codehaus.xfire.client.XFireProxyFactory; importimportimportimportorg.codehaus.xfire.service.Service; importimportimportimportorg.codehaus.xfire.service.binding.ObjectServiceFactory; importimportimportimportwebservice.xfire.selfobj.server.model.Address; /** *XFire客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-23 */ publicpublicpublicpublicclassclassclassclassClient{ privateprivateprivateprivatestaticstaticstaticstaticStringurl= "http://127.0.0.1:8089/myxfire/services/AddressManager"; publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidgetServerList(){ ServiceserviceModel=newnewnewnew ObjectServiceFactory().create(IClientAddressManager.classclassclassclass); trytrytrytry{ IClientAddressManagerservice=(IClientAddressManager)newnewnewnew XFireProxyFactory().create(serviceModel,url); List
list=(ArrayList
) service.getAddressList(); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第92页 共207 页 System.out.println("Listsize:"+list.size()); forforforfor(Iterator
iter=list.iterator();iter.hasNext();){ Addressaddress=iter.next(); System.out.println(address); } }catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidsetServerList(){ ServiceserviceModel=newnewnewnew ObjectServiceFactory().create(IClientAddressManager.classclassclassclass); trytrytrytry{ IClientAddressManagerservice=(IClientAddressManager)newnewnewnew XFireProxyFactory().create(serviceModel,url); List
list=newnewnewnewArrayList
(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); list.add(address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); list.add(address); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第93页 共207 页 List
returnList=service.setAddressList(list); System.out.println("Listsize:"+returnList.size()); forforforfor(Iterator
iter=returnList.iterator(); iter.hasNext();){ address=iter.next(); System.out.println(address); } }catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ getServerList(); setServerList(); } } 以上都做完了就可以运行你的客户端代码运行结果是: Listsize:2 webservice.xfire.selfobj.server.model.Address@b61fd1id号:1address: Haidiancity:BeiJingcountry:ChinapostalCode:100081province:Beijing array:1list:[1,2,3]map:{}isExist:falseinnerClass.name:服务 端:Address.InnerClass webservice.xfire.selfobj.server.model.Address@e2dae9id号:2address: Chaoyangcity:BeiJingcountry:ChinapostalCode:100081province: Beijingarray:Alist:[1,2,3]map:{}isExist:true innerClass.name:服务端:Address.InnerClass Listsize:2 webservice.xfire.selfobj.server.model.Address@f99ff5id号:1address: Haidiancity:BeiJingcountry:ChinapostalCode:100081province:Beijing array:1list:[1,2,3]map:{}isExist:falseinnerClass.name:服务 端:Address.InnerClass webservice.xfire.selfobj.server.model.Address@74c3aaid号:2address: Chaoyangcity:BeiJingcountry:ChinapostalCode:100081province: Beijingarray:Alist:[1,2,3]map:{}isExist:true innerClass.name:服务端:Address.InnerClass 在这里我们说下要注意的地方,就是关于这个自定义对象的问题,自定义对象这个包名客户 端与服务端一定要保证包名和类名一样也可以使用同一个要不会找不到这块经过实验已经 获得证实,如果读者有更好的建议请与我们联系谢谢。 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第94页 共207 页 3.3.1.23.3.1.23.3.1.23.3.1.2 传递传递传递传递MapMapMapMap 刚才的 Map 传递是在你定义好的对象里面传递的,现在要传递的是直接服务端的方法 返回一个 Map。来看代码实现: 接口代码: Java 代码: /* *文件名: IAddressManagerMap.java * *创建日期: 2008-7-24 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.selfmap; importimportimportimportjava.util.Map; importimportimportimportwebservice.xfire.selfobj.server.model.Address; /** *实现MAP的传递,本地与服务器必须用同一个接口 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-24 */ publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceIAddressManagerMap{ publicpublicpublicpublicMapgetAddressMap(); publicpublicpublicpublicMapsetAddressMap(Mapmap); } 对应的接口实现服务端: Java 代码: /* Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第95页 共207 页 *文件名: AddressManagerMap.java * *创建日期: 2008-7-11 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.selfmap.server; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.Map; importimportimportimportwebservice.xfire.selfmap.IAddressManagerMap; importimportimportimportwebservice.xfire.selfobj.server.model.Address; /** *传递Map的WebService业务 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ publicpublicpublicpublicclassclassclassclassAddressManagerMapimplementsimplementsimplementsimplementsIAddressManagerMap{ privateprivateprivateprivateintintintintrequestCount=0; publicpublicpublicpublicMapgetAddressMap(){ requestCount++; System.out.println("requestCount="+requestCount); MapreturnMap=newnewnewnewHashMap(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第96页 共207 页 address.setArray(newnewnewnewString[]{"1","2","3"}); returnMap.put(address.getIdentifier(),address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); returnMap.put(address.getIdentifier(),address); returnreturnreturnreturnreturnMap; } publicpublicpublicpublicMapsetAddressMap(Mapmap){ requestCount++; System.out.println("requestCount="+requestCount); returnreturnreturnreturnmap; } } 除了以上的做法还有做一个事情就是绑定 aegis,这个在这说下 aegis 的绑定有个规则就是必 须和你服务端的接口叫一样的名字并且放在同一目录下,例如我们的是 IAddressManagerMap 接口那么我们的 aegis 就应该叫做 IAddressManagerMap. aegis.xml 并且 要和 IAddressManagerMap 放在同一目录下。命名规范就是:接口名字. aegis.xml 现在给出 IAddressManagerMap. aegis.xml 的代码: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第97页 共207 页 这里简单介绍一下: method:表示你要执行的方法,name是对应的方法名字。 return-type:表示你要返回的类型里面有个 componentType这个就是表示你返回的类型。 parameter:表示方法所要的参数 index是参数索引表示第几个参数从 0开始计算。 componentType也是表示你参数传递的类型。 还要说一点就是大家认为我返回的是 Map类型你为什么不写而写 Map里面的类型呢,其实在你 返回数据和设置数据的时候他检查的是你的 Map里的类型是什么类型你只要告诉他里面的真实 类型就行了。 来看下面的客户端: Java代码: /* *文件名: Client.java * *创建日期: 2008-7-23 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.selfmap.client; importimportimportimportjava.net.MalformedURLException; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.Iterator; importimportimportimportjava.util.Map; importimportimportimportorg.codehaus.xfire.client.XFireProxyFactory; importimportimportimportorg.codehaus.xfire.service.Service; importimportimportimportorg.codehaus.xfire.service.binding.ObjectServiceFactory; importimportimportimportwebservice.xfire.selfmap.IAddressManagerMap; importimportimportimportwebservice.xfire.selfobj.server.model.Address; /** *XFire客户端 * *@author@author@author@authorAlong Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第98页 共207 页 * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-23 */ publicpublicpublicpublicclassclassclassclassClient{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinalStringurl= "http://127.0.0.1:8089/myxfire/services/AddressManagerMap"; privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinalStringnamespace= "http://selfmap.xfire.webservice/IAddressManagerMap"; publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidgetAddressMap(){ ServiceserviceModel=newnewnewnew ObjectServiceFactory().create(IAddressManagerMap.classclassclassclass,nullnullnullnull,namespace, nullnullnullnull); trytrytrytry{ IAddressManagerMapservice=(IAddressManagerMap)newnewnewnew XFireProxyFactory().create(serviceModel,url); Mapmap=(Map) service.getAddressMap(); System.out.println("Mapsize:"+map.size()); forforforfor(Iteratoriter=map.keySet().iterator(); iter.hasNext();){ Integerkey=iter.next(); Addressaddress=map.get(key); System.out.println(address); } }catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidsetAddressMap(){ ServiceserviceModel=newnewnewnew ObjectServiceFactory().create(IAddressManagerMap.classclassclassclass,nullnullnullnull,namespace, nullnullnullnull); trytrytrytry{ IAddressManagerMapservice=(IAddressManagerMap)newnewnewnew XFireProxyFactory().create(serviceModel,url); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第99页 共207 页 Mapmap=newnewnewnewHashMap(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); map.put(address.getIdentifier(),address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); map.put(address.getIdentifier(),address); MapmapReturn=(Map) service.setAddressMap(map); System.out.println("Mapsize:"+mapReturn.size()); forforforfor(Iteratoriter=mapReturn.keySet().iterator(); iter.hasNext();){ Integerkey=iter.next(); address=mapReturn.get(key); System.out.println(address); } }catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ getAddressMap(); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第100页 共207 页 setAddressMap(); } } 这里大家可能又有些疑问了,观察仔细的朋友可能发现了一点问题,就是为什么上面的客户端实 现的代码和前几个实现客户端的代码有些不相同呢,在这里我说明一下为什么,由于以前的实现 我们没有准确的根据命名空间去查找,给出源码来看看: publicpublicpublicpublicorg.codehaus.xfire.service.Servicecreate(Classclazz) { returnreturnreturnreturncreate(clazz,(Map)nullnullnullnull); } publicpublicpublicpublicorg.codehaus.xfire.service.Servicecreate(Classclazz,Map properties) { returnreturnreturnreturncreate(clazz,(String)nullnullnullnull,(String)nullnullnullnull,properties); } 所以在你即时绑定了 aegis 对应的返回类型也不会被找到。运行结果: 客户端: Mapsize:2 webservice.xfire.selfobj.server.model.Address@1d80e6did号:2address: Chaoyangcity:BeiJingcountry:ChinapostalCode:100081province: Beijingarray:Alist:[1,2,3]map: {2=webservice.xfire.selfobj.server.model.Address$InnerClass@19b5393, 1=webservice.xfire.selfobj.server.model.Address$InnerClass@8bdcd2, 3=webservice.xfire.selfobj.server.model.Address$InnerClass@4e79f1} isExist:trueinnerClass.name:服务端:Address.InnerClass webservice.xfire.selfobj.server.model.Address@27e353id号:1address: Haidiancity:BeiJingcountry:ChinapostalCode:100081province:Beijing array:1list:[1,2,3]map: {2=webservice.xfire.selfobj.server.model.Address$InnerClass@bd928a, 1=webservice.xfire.selfobj.server.model.Address$InnerClass@1dfc547, 3=webservice.xfire.selfobj.server.model.Address$InnerClass@10f6d3} isExist:falseinnerClass.name:服务端:Address.InnerClass Mapsize:2 webservice.xfire.selfobj.server.model.Address@a31e1bid号:2address: Chaoyangcity:BeiJingcountry:ChinapostalCode:100081province: Beijingarray:Alist:[1,2,3]map: {2=webservice.xfire.selfobj.server.model.Address$InnerClass@10da5eb, 1=webservice.xfire.selfobj.server.model.Address$InnerClass@1081d2e, 3=webservice.xfire.selfobj.server.model.Address$InnerClass@1b3f829} isExist:trueinnerClass.name:服务端:Address.InnerClass Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第101页 共207 页 webservice.xfire.selfobj.server.model.Address@698403id号:1address: Haidiancity:BeiJingcountry:ChinapostalCode:100081province:Beijing array:1list:[1,2,3]map: {2=webservice.xfire.selfobj.server.model.Address$InnerClass@15a0305, 1=webservice.xfire.selfobj.server.model.Address$InnerClass@7c4c51, 3=webservice.xfire.selfobj.server.model.Address$InnerClass@765a16} isExist:falseinnerClass.name:服务端:Address.InnerClass 如果不按照我上面的写那么你会得到一个 NULL 值,在网上我也看到很多人在问在这里我 们已经给予解决,如果那块说的不对请您加我们的 QQ来指点一下再次谢过。 3.3.23.3.23.3.23.3.2 异常处理 直接看代码: 异常描述类: Java 代码: /* *文件名: HelloWordExceptionDetail.java * *创建日期: 2008-7-24 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.exception; importimportimportimportjava.io.Serializable; /** *描述异常的数据类 一定要有默认构造函数 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-24 */ publicpublicpublicpublicclassclassclassclassHelloWordExceptionDetailimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=1312467612597288019L; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第102页 共207 页 privateprivateprivateprivateStringmessage; publicpublicpublicpublicHelloWordExceptionDetail(){ } publicpublicpublicpublicHelloWordExceptionDetail(Stringmessage){ thisthisthisthis.message=message; } publicpublicpublicpublicStringgetMessage(){ returnreturnreturnreturnmessage; } publicpublicpublicpublicvoidvoidvoidvoidsetMessage(Stringmessage){ thisthisthisthis.message=message; } } 这个类是异常描述类这里主要说一下就是他必须有构造函数,别的没有什么了。 异常类: Java 代码: /* *文件名: HelloWordException.java * *创建日期: 2008-7-24 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.exception; importimportimportimportorg.codehaus.xfire.fault.FaultInfoException; /** *异常类 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-24 */ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第103页 共207 页 publicpublicpublicpublicclassclassclassclassHelloWordExceptionextendsextendsextendsextendsFaultInfoException{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=8373919408375406129L; privateprivateprivateprivateHelloWordExceptionDetailhwd; publicpublicpublicpublicHelloWordException(Stringmessage,HelloWordExceptionDetailhwd){ supersupersupersuper(message); thisthisthisthis.hwd=hwd; } publicpublicpublicpublicHelloWordExceptionDetailgetFaultInfo(){ returnreturnreturnreturnhwd; } } 这个里主要继承了 FaultInfoException 类,它是处理异常基本类。 服务接口类: Java 代码: /* *文件名: IHelloWorldService.java * *创建日期: 2008-7-24 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.exception; /** *服务和客户端必须保证包名一样,提供对应的服务接口 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-24 */ publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceIHelloWorldService{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第104页 共207 页 publicpublicpublicpublicStringgetException(Stringmessage)throwsthrowsthrowsthrowsHelloWordException; } 服务对应接口的实现类: /* *文件名: HelloWorldServiceImpl.java * *创建日期: 2008-7-24 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.exception.server; importimportimportimportwebservice.xfire.exception.HelloWordException; importimportimportimportwebservice.xfire.exception.HelloWordExceptionDetail; importimportimportimportwebservice.xfire.exception.IHelloWorldService; /** *对应的服务实现 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-24 */ publicpublicpublicpublicclassclassclassclassHelloWorldServiceImplimplementsimplementsimplementsimplementsIHelloWorldService{ /* * *(non-Javadoc) * *@see webservice.xfire.exception.IHelloWorldService#getException(java.lang.String) */ publicpublicpublicpublicStringgetException(Stringmessage)throwsthrowsthrowsthrowsHelloWordException{ ifififif(message.equals("")){ throwthrowthrowthrownewnewnewnewHelloWordException("参数不能为空 ",newnewnewnew HelloWordExceptionDetail("异常测试成功")); } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第105页 共207 页 System.out.println(message); returnreturnreturnreturn"没有异常"; } } 客户端: Java 代码: /* *文件名: Client.java * *创建日期: 2008-7-24 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.exception.client; importimportimportimportjava.net.MalformedURLException; importimportimportimportorg.codehaus.xfire.client.XFireProxyFactory; importimportimportimportorg.codehaus.xfire.service.Service; importimportimportimportorg.codehaus.xfire.service.binding.ObjectServiceFactory; importimportimportimportwebservice.xfire.exception.HelloWordException; importimportimportimportwebservice.xfire.exception.IHelloWorldService; /** * * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-24 */ publicpublicpublicpublicclassclassclassclassClient{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinalStringurl= "http://127.0.0.1:8089/myxfire/services/HelloWordException"; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第106页 共207 页 privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinalStringnamespace= "http://exception.xfire.webservice/HelloWordException"; /** *@param@param@param@paramargs */ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ ServiceserviceModel=newnewnewnew ObjectServiceFactory().create(IHelloWorldService.classclassclassclass,nullnullnullnull,namespace, nullnullnullnull); trytrytrytry{ IHelloWorldServiceclient=(IHelloWorldService)newnewnewnew XFireProxyFactory().create(serviceModel,url); Stringsuccess=client.getException("成功"); System.out.println(success); client.getException(""); }catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); }catchcatchcatchcatch(HelloWordExceptione){ System.out.println(e.getFaultInfo().getMessage()); //e.printStackTrace(); } } } 这个没有什么好说的了最重要的就是记住描述类要有构造函数,我个人认为写类要按照规范 写这样可以避免无谓的错误。 3.3.33.3.33.3.33.3.3 Handler Handler Handler Handler 处理 服务端接口: Java 代码: /* *文件名: IHelloWorldService.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第107页 共207 页 * */ packagepackagepackagepackagewebservice.xfire.handlers; /** * * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceIHelloWorldService{ publicpublicpublicpublicStringgetStr(Stringmessage); } 对应的实现类: Java 代码: /* *文件名: HelloWorldService.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.handlers.server; importimportimportimportwebservice.xfire.handlers.IHelloWorldService; /** * * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicclassclassclassclassHelloWorldServiceimplementsimplementsimplementsimplementsIHelloWorldService{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第108页 共207 页 /* * *(non-Javadoc) * *@see webservice.xfire.handlers.IHelloWorldService#getStr(java.lang.String) */ publicpublicpublicpublicStringgetStr(Stringmessage){ System.out.println("Receivemessage:"+message); returnreturnreturnreturnmessage; } } 服务端前置的 Handle 类: Java 代码: /* *文件名: HelloWordHandler.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.handlers.server; importimportimportimportorg.codehaus.xfire.MessageContext; importimportimportimportorg.codehaus.xfire.handler.AbstractHandler; /** *服务端Handler类 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicclassclassclassclassServerHelloWordInHandlerextendsextendsextendsextendsAbstractHandler{ /* Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第109页 共207 页 * *(non-Javadoc) * *@see org.codehaus.xfire.handler.Handler#invoke(org.codehaus.xfire.MessageContext) */ publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextctx)throwsthrowsthrowsthrowsException{ System.out.println("调用服务端之前做的一件事"); ctx.setProperty("myparam","ServerHelloWordInHandler传递的参数"); System.out.println("ServerHelloWordInHandlerExit."); } } 服务端后置 Handler 类: Java 代码: /* *文件名: HelloWordHandler.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.handlers.server; importimportimportimportorg.codehaus.xfire.MessageContext; importimportimportimportorg.codehaus.xfire.handler.AbstractHandler; /** *服务端Handler类 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicclassclassclassclassServerHelloWordOutHandlerextendsextendsextendsextendsAbstractHandler{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第110页 共207 页 /* * *(non-Javadoc) * *@see org.codehaus.xfire.handler.Handler#invoke(org.codehaus.xfire.MessageContext) */ publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextctx)throwsthrowsthrowsthrowsException{ System.out.println("调用服务端之后做的一件事"); System.out.println(ctx.getProperty("myparam")); System.out.println("ServerHelloWordOutHandlerExit."); } } 客户端前置 Handler 类: Java 代码: /* *文件名: AddHeaderHandler.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.handlers.client; importimportimportimportorg.codehaus.xfire.MessageContext; importimportimportimportorg.codehaus.xfire.handler.AbstractHandler; /** *写入版本号的Handler类 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicclassclassclassclassClientHeaderOutHandlerextendsextendsextendsextendsAbstractHandler{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第111页 共207 页 publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextctx)throwsthrowsthrowsthrowsException{ System.out.println("客户端之前做的事"); ctx.setProperty("myparam","ClientHeaderOutHandler传递的参数"); System.out.println("ClientHeaderOutHandlerExit."); } } 客户端后置 Handler 类: Java 代码: /* *文件名: AddHeaderHandler.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.handlers.client; importimportimportimportorg.codehaus.xfire.MessageContext; importimportimportimportorg.codehaus.xfire.handler.AbstractHandler; /** *写入版本号的Handler类 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicclassclassclassclassClientHeaderInHandlerextendsextendsextendsextendsAbstractHandler{ publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextctx)throwsthrowsthrowsthrowsException{ System.out.println("客户端之后做的事"); System.out.println(ctx.getProperty("myparam")); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第112页 共207 页 System.out.println("ClientHeaderInHandlerExit."); } } 客户端类: Java 代码: /* *文件名: Client.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.handlers.client; importimportimportimportjava.net.MalformedURLException; importimportimportimportorg.codehaus.xfire.client.Client; importimportimportimportorg.codehaus.xfire.client.XFireProxyFactory; importimportimportimportorg.codehaus.xfire.service.Service; importimportimportimportorg.codehaus.xfire.service.binding.ObjectServiceFactory; importimportimportimportwebservice.xfire.handlers.IHelloWorldService; /** * * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicclassclassclassclassClientHandlers{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinalStringurl= "http://127.0.0.1:8089/myxfire/services/HelloWordHandler"; privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinalStringnamespace= "http://handlers.xfire.webservice/HelloWordHandler"; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第113页 共207 页 /** *@param@param@param@paramargs */ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ ServiceserviceModel=newnewnewnew ObjectServiceFactory().create(IHelloWorldService.classclassclassclass,nullnullnullnull,namespace, nullnullnullnull); trytrytrytry{ IHelloWorldServiceclientService=(IHelloWorldService)newnewnewnew XFireProxyFactory().create(serviceModel,url); Clientclient=Client.getInstance(clientService); client.addInHandler(newnewnewnewClientHeaderInHandler()); client.addOutHandler(newnewnewnewClientHeaderOutHandler()); System.out.println(clientService.getStr("测试成功")); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } } } 来看对应的部署文件 services.xml: HelloWordHandler http://handlers.xfire.webservice/HelloWordHandler webservice.xfire.handlers.IHelloWorldService webservice.xfire.handlers.server.HelloWorldS ervice application 这里我们部署的是在服务端前置和后置的类如果你这么部署了他会在调用方法之前和之后做前 置和后置类。 再看输出: 在客户端的输出: 客户端之前做的事 ClientHeaderOutHandlerExit. 客户端之后做的事 ClientHeaderOutHandler传递的参数 ClientHeaderInHandlerExit. 测试成功 在服务端的输出: 调用服务端之前做的一件事 ServerHelloWordInHandlerExit. Receivemessage:测试成功 调用服务端之后做的一件事 ServerHelloWordInHandler传递的参数 ServerHelloWordOutHandlerExit. 3.3.43.3.43.3.43.3.4 文件上传处理 服务接口: Java 代码: /* *文件名: IFileTransport.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.filetransport; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第115页 共207 页 importimportimportimportjavax.activation.DataHandler; /** *传送文件的接口,本地与服务器必须用同一个接口 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceIFileTransport{ publicpublicpublicpublicDataHandlergetFile(); publicpublicpublicpublicStringuploadFile(DataHandlerhandler); } 对应的接口实现类: Java 代码: /* *文件名: FileTransportImpl.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.filetransport.server; importimportimportimportjava.io.BufferedReader; importimportimportimportjava.io.File; importimportimportimportjava.io.FileOutputStream; importimportimportimportjava.io.IOException; importimportimportimportjava.io.InputStreamReader; importimportimportimportjava.io.OutputStreamWriter; importimportimportimportjavax.activation.DataHandler; importimportimportimportjavax.activation.FileDataSource; importimportimportimportwebservice.xfire.filetransport.IFileTransport; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第116页 共207 页 /** *服务端传送文件的实现类,服务的提供者。 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicclassclassclassclassFileTransportImplimplementsimplementsimplementsimplementsIFileTransport{ /* *(non-Javadoc) * *@seewebservice.xfire.filetransport.IFileTransport#getFile() */ publicpublicpublicpublicDataHandlergetFile(){ System.out.println("getFileiscalled"); StringfileName="server.txt"; DataHandlerdh=newnewnewnewDataHandler(newnewnewnewFileDataSource( FileTransportImpl.classclassclassclass.getResource(fileName).getPath())); returnreturnreturnreturndh; } /* *(non-Javadoc) * *@see webservice.xfire.filetransport.IFileTransport#uploadFile(javax.activation.Da taHandler) */ publicpublicpublicpublicStringuploadFile(DataHandlerhandler){ System.out.println("uploadFileiscalled"); Filefile=newnewnewnewFile("fromClient.txt"); ifififif(handler==nullnullnullnull){ returnreturnreturnreturn"failure"; } InputStreamReaderinput=nullnullnullnull; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第117页 共207 页 OutputStreamWriterfos=nullnullnullnull; BufferedReaderbr=nullnullnullnull; trytrytrytry{ input=newnewnewnewInputStreamReader(handler.getInputStream(),"UTF-8"); fos=newnewnewnewOutputStreamWriter(newnewnewnewFileOutputStream(file),"UTF-8"); br=newnewnewnewBufferedReader(input); StringtmpStr=nullnullnullnull; whilewhilewhilewhile((tmpStr=br.readLine())!=nullnullnullnull){ fos.write(tmpStr); fos.write("\r\n"); } } catchcatchcatchcatch(IOExceptione){ e.printStackTrace(); } finallyfinallyfinallyfinally{ ifififif(input!=nullnullnullnull){ trytrytrytry{ input.close(); br.close(); } catchcatchcatchcatch(IOExceptione){ e.printStackTrace(); } } ifififif(fos!=nullnullnullnull){ trytrytrytry{ fos.close(); } catchcatchcatchcatch(IOExceptione){ e.printStackTrace(); } } } returnreturnreturnreturn"Successfilesavedonserver.At:"+file.getAbsolutePath(); } } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第118页 共207 页 客户端: Java 代码: /* *文件名: Client.java * *创建日期: 2008-7-25 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.xfire.filetransport.client; importimportimportimportjava.io.BufferedReader; importimportimportimportjava.io.File; importimportimportimportjava.io.FileOutputStream; importimportimportimportjava.io.IOException; importimportimportimportjava.io.InputStreamReader; importimportimportimportjava.io.OutputStreamWriter; importimportimportimportjava.lang.reflect.Proxy; importimportimportimportjava.net.MalformedURLException; importimportimportimportjavax.activation.DataHandler; importimportimportimportjavax.activation.FileDataSource; importimportimportimportorg.codehaus.xfire.client.XFireProxy; importimportimportimportorg.codehaus.xfire.client.XFireProxyFactory; importimportimportimportorg.codehaus.xfire.service.Service; importimportimportimportorg.codehaus.xfire.service.binding.ObjectServiceFactory; importimportimportimportorg.codehaus.xfire.soap.SoapConstants; importimportimportimportwebservice.xfire.filetransport.IFileTransport; /** *测试文件传输的客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-25 */ publicpublicpublicpublicclassclassclassclassClient{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第119页 共207 页 privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinalStringurl= "http://127.0.0.1:8089/myxfire/services/FileTransport"; privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinalStringnamespace= "http://filetransport.xfire.webservice/FileTransport"; publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidgetFileFromServer(){ InputStreamReaderinput=nullnullnullnull; OutputStreamWriterfos=nullnullnullnull; BufferedReaderbr=nullnullnullnull; Filefile=nullnullnullnull; ServiceserviceModel=newnewnewnewObjectServiceFactory().create( IFileTransport.classclassclassclass,nullnullnullnull,namespace,nullnullnullnull); trytrytrytry{ IFileTransportservice=(IFileTransport)newnewnewnewXFireProxyFactory() .create(serviceModel,url); org.codehaus.xfire.client.Clientclient=((XFireProxy)Proxy .getInvocationHandler(service)).getClient(); //client.setProperty(HttpTransport.CHUNKING_ENABLED,"true"); client.setProperty(SoapConstants.MTOM_ENABLED,"true"); DataHandlerhandler=service.getFile(); file=newnewnewnewFile("fromServer.txt"); ifififif(handler==nullnullnullnull){ System.out.println("failure"); } input=newnewnewnewInputStreamReader(handler.getInputStream(),"UTF-8"); fos=newnewnewnewOutputStreamWriter(newnewnewnewFileOutputStream(file),"UTF-8"); br=newnewnewnewBufferedReader(input); StringtmpStr=nullnullnullnull; whilewhilewhilewhile((tmpStr=br.readLine())!=nullnullnullnull){ fos.write(tmpStr); fos.write("\r\n"); } } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第120页 共207 页 catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } catchcatchcatchcatch(IOExceptione){ e.printStackTrace(); } finallyfinallyfinallyfinally{ ifififif(input!=nullnullnullnull){ trytrytrytry{ input.close(); br.close(); } catchcatchcatchcatch(IOExceptione){ e.printStackTrace(); } } ifififif(fos!=nullnullnullnull){ trytrytrytry{ fos.close(); } catchcatchcatchcatch(IOExceptione){ e.printStackTrace(); } } } System.out.println("Successfilesavedonclinet.At:" +file.getAbsolutePath()); } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidsendFileToServer(){ StringfileName="client.txt"; trytrytrytry{ ServiceserviceModel=newnewnewnewObjectServiceFactory().create( IFileTransport.classclassclassclass,nullnullnullnull,namespace,nullnullnullnull); IFileTransportservice=(IFileTransport)newnewnewnewXFireProxyFactory() .create(serviceModel,url); org.codehaus.xfire.client.Clientclient=((XFireProxy)Proxy .getInvocationHandler(service)).getClient(); //client.setProperty(HttpTransport.CHUNKING_ENABLED,"true"); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第121页 共207 页 client.setProperty(SoapConstants.MTOM_ENABLED,"true"); DataHandlerhandler=newnewnewnewDataHandler(newnewnewnewFileDataSource( Client.classclassclassclass.getResource(fileName).getPath())); StringreturnString=service.uploadFile(handler); System.out.println(returnString); } catchcatchcatchcatch(MalformedURLExceptione){ e.printStackTrace(); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ getFileFromServer(); sendFileToServer(); } } 在这里注意一点就是编码格式:如果你不对格式做处理上传后的文件你用 UE 打开或者 EditPlus 打开会看见增加了不知道是什么的乱码。 对应的服务部署 services.xml: FileTransport http://filetransport.xfire.webservice/FileTransport webservice.xfire.filetransport.IFileTransport webservice.xfire.filetransport.server.FileTransp ortImpl request true Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第122页 共207 页 3.4 XFire 与Spring 集成 在和Spring 集成的时候主要有需要配置 Web.xml, applicationContext.xml, xfire- servlet.xml 这3个文件,剩下的代码都是上面提供的一样。 Web.xml 配置代码: contextConfigLocation classpath:applicationContext.xml,classpath:org/codehaus/xfire/s pring/xfire.xml org.springframework.web.context.ContextLoaderListener org.springframework.web.util.IntrospectorCleanupListener XFireServlet org.codehaus.xfire.spring.XFireSpringServlet XFireServlet Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第123页 共207 页 /services/* applicationContext.xml 配置代码: xfire-servlet.xml 代码: HelloWorldSimple http://simple.xfire.webservice/HelloWorld Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第124页 共207 页 webservice.xfire.simple.HelloWorld AddressManager http://server.selfobj.xfire.webservice/AddressManager webservice.xfire.selfobj.server.AddressManager http://selfmap.xfire.webservice/IAddressManagerMap AddressManagerMap webservice.xfire.selfmap.IAddressManagerMap Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第125页 共207 页 http://handlers.xfire.webservice/HelloWordHandler HelloWordHandler webservice.xfire.handlers.IHelloWorldService http://exception.xfire.webservice/HelloWordException HelloWordException webservice.xfire.exception.IHelloWorldService Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第126页 共207 页 FileTransport http://filetransport.xfire.webservice/FileTransport webservice.xfire.filetransport.IFileTransport true Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第127页 共207 页 在xfire-servlet.xml 里面的代码都是 4.2 和4.3 你写的代码只不过在这是和 Spring 做了结合, 测试结果也应该和上面的一样就对了。 3.5使用 WSDL 生成客户端 在很多项目中往往用户只给你提供了 WSDL 并不给你提供任何数据,所以需要你自己通过 Xfire 本身提供的 API 来生成客户端代码。 一般在开发过程中使用 ANT 进行客户端生成,在这里就以它为例。 Ant 生成客户端代码: 在这里说明2个地方: 第一classpathref这个里面的devlib.classpath是你所有的包(*.jar) 第二 binding有下两种不同的方式: (1)jaxb (2)xmlbeans 这里注意:如果使用xmlbeans你需要先生成wsdl的XMLBeans。所以在这里我们使用jaxb 这里使用List的那个例子为例: 通过上面的ant你会生成如下结构: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第128页 共207 页 这就是用Ant帮你生成的 但是里面的TestClient.java是由我自己编写的客户端。 先贴出代码在做相关解释 如下: /* *文件名: TestClient.java * *创建日期: 2008-12-12 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackageorg.xiaozhi.client; importimportimportimportjava.util.List; importimportimportimportorg.xiaozhi.addressManager.AddressManagerClient; importimportimportimportorg.xiaozhi.addressManager.AddressManagerPortType; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第129页 共207 页 importimportimportimportwebservice.xfire.selfobj.server.model.Address; importimportimportimportwebservice.xfire.selfobj.server.model.ArrayOfAddress; importimportimportimportwebservice.xfire.selfobj.server.model.ObjectFactory; /** * * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-12-12 */ publicpublicpublicpublicclassclassclassclassTestClient{ /** *@param@param@param@paramargs */ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ getAddressList(); setAddressList(); } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidgetAddressList(){ AddressManagerClientclient=newnewnewnewAddressManagerClient(); AddressManagerPortTypeservice= client.getAddressManagerHttpPort(); ArrayOfAddressaddress=service.getAddressList(); List
listAddress=address.getAddress(); forforforfor(intintintinti=0;iaddressList=list.getAddress(); forforforfor(intintintinti=0;i 一般人家是为了本地做测试,所以在你使用的时候要改成他的外网地址才行然后在生成。 3.6.SOAP 头进行验证 WebService 的安全策略有很多在这里我们这介绍用 soa 的头验证的方式。 XFire 是通过 Handler 进行报文的发送和接受的。现在我们来简单的看一个代码实例: 服务端代码: /* *文件名: ServerHeader.java * *创建日期: 2008-12-29 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.xfire.soaheader.server; importimportimportimportorg.codehaus.xfire.MessageContext; importimportimportimportorg.codehaus.xfire.XFireRuntimeException; importimportimportimportorg.codehaus.xfire.handler.AbstractHandler; importimportimportimportorg.jdom.Element; /** * * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-12-29 */ publicpublicpublicpublicclassclassclassclassServerHeaderextendsextendsextendsextendsAbstractHandler{ /* * *(non-Javadoc) * *@see * org.codehaus.xfire.handler.Handler#invoke(org.codehaus.xfire.MessageC Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第132页 共207 页 ontext *) */ publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextmessage)throwsthrowsthrowsthrowsException{ Elementheader=message.getInMessage().getHeader(); ifififif(header==nullnullnullnull){ throwthrowthrowthrownewnewnewnewXFireRuntimeException("MissingSOAPheader"); } Elementtoken=header.getChild("AuthenticationToken"); Stringusername=token.getChild("username").getValue(); System.out.println("用户名==="+username); System.out.println("header"+header.toString()); } } 在XFire 里通过继承 AbstractHandler可以想头里写东西也可以获取头的信息。以上是获取 头的信息。其实这个 AbstractHandler就想一个拦截器一样就是在你调用服务端方法的时候 做了一个验证的事情。除了以上代码的编写你还要声明一下请看代码如下。 HelloWorldSimple http://simple.xfire.webservice/HelloWorld webservice.xfire.simple.HelloWorld Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第133页 共207 页 以上是和 Spring结合使用的。这样就完成了头的配置和编写。 这样你每次调用服务里的方法时就要写头的信息也就是客户端要做的代码如下: /* *文件名: TestHellword.java * *创建日期: 2008-12-30 * *Copyright(C)2008,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackageorg.xiaozhi.client; importimportimportimportjava.lang.reflect.Proxy; importimportimportimportorg.codehaus.xfire.MessageContext; importimportimportimportorg.codehaus.xfire.client.Client; importimportimportimportorg.codehaus.xfire.client.XFireProxy; importimportimportimportorg.codehaus.xfire.handler.AbstractHandler; importimportimportimportorg.jdom.Element; importimportimportimportorg.xiaozhi.helloWorld.HelloWorldSimpleClient; importimportimportimportorg.xiaozhi.helloWorld.HelloWorldSimplePortType; /** * * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2008-12-30 */ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第134页 共207 页 publicpublicpublicpublicclassclassclassclassTestHellwordextendsextendsextendsextendsAbstractHandler{ publicpublicpublicpublicTestHellword(){ } /** *@param@param@param@paramargs */ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ HelloWorldSimpleClientclient=newnewnewnewHelloWorldSimpleClient(); HelloWorldSimplePortTypeservice= client.getHelloWorldSimpleHttpPort(); XFireProxyproxy=(XFireProxy) Proxy.getInvocationHandler(service); Clientc=proxy.getClient(); c.addOutHandler(newnewnewnewTestHellword()); service.hello("xiaozhi"); } /* * *(non-Javadoc) * *@see * org.codehaus.xfire.handler.Handler#invoke(org.codehaus.xfire.MessageC ontext *) */ publicpublicpublicpublicvoidvoidvoidvoidinvoke(MessageContextmessage)throwsthrowsthrowsthrowsException{ Elementel=newnewnewnewElement("Header"); Elementtoken=newnewnewnewElement("AuthenticationToken"); Elementusername=newnewnewnewElement("username"); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第135页 共207 页 username.addContent("hellworld"); username.setText("xiaozhi123"); token.addContent(username); el.addContent(token); System.out.println(el.getChild("AuthenticationToken")); message.getCurrentMessage().setHeader(el); } } 这样就编写完事了,在这里不做过多解释里相信读者通过代码的展示可以明白的。 4.CXF 4.CXF 4.CXF 4.CXF 篇篇篇篇 4.14.14.14.1 CXF CXF CXF CXF 简介简介简介简介 4.1.14.1.14.1.14.1.1 CXF CXF CXF CXF 的由来 Apache CXF 项目是由 Objectweb Celtix 和Codehaus XFire 合并成立的。Objectweb Celtix 是由 IONA 公司赞助、于 2005 年成立的开源 Java ESB 产品,XFire 则是业界知名的 SOAP 堆栈。合并后的 Apache CXF 融合该两个开源项目的功能精华,提供了实现 SOA 所需要的 核心 ESB 功能框架,包括 SOA 服务创建,服务路由,及一系列企业级 QoS 功能。此次发 布代表了 Apache CXF 开发人员及社区用户一年的努力结果,并标志 Apache CXF 软件的进 一步成熟,成为实现 SOA 的优秀技术解决方案之一。2.1 版本的 CXF,已经是一个正式的 Apache 顶级项目。 4.1.24.1.24.1.24.1.2 CXF CXF CXF CXF 的功能 CXF 提供了一套创建 SOA 服务的基础设施框架,用户由此可以按照自己喜欢的编程模 式,利用 Apache CXF 提供的简单易用工具(包括 Maven 插件),创建适合 SOA 环境的任何 WEB服务,包括 SOAP/HTTP 服务及 REST/HTTP 服务。Apache CXF 可扩展的插拔式架构 不但支持 XML 消息格式和 HTTP 通信协议,而且还支持基于其他通信协议如 IIOP 和非 XML 消息格式如 CORBA CDL 或JSON。 主要功能列表如下: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第136页 共207 页 � 支持 JAX-WS 2.1,部署 JAX-WS 已经更新至 JAX-WS 2.1 规范。 � JAX-RS 0.6 REST 的初期部署基于服务框架。 � Javascript 客户端生成和支持,SOAP 基于于端点的可以有 Javascript 带着 JS URL 自动 创建。 � CORBA 的约束力来自 Yoko,JAX-WS 客户端/服务器能使 IIOP 与CORBA 进程进行交 互。 � 支持 Java to WSDL、WSDL to Java、XSD to WSDL、WSDL to XML、WSDL to SOAP、 WSDL to Service。 � 支持 XmlBeans 运行库,允许数据模型使用 XmlBeans。 � 支持 SOAP1.1&1.2、WSDL1&2、WS-Addressing、WS-Policy、WS-RM、WS-Security 和WS-I BasicProfile。 � 支持 JAX-WS、JAX-WSA、JSR-181、SAAJ。 � Apache CXF 提供方便的 Spring 整合方法,可以通过注解、Spring 标签式配置来暴露 WebServices 和消费 WebServices。 4.24.24.24.2 CXF CXF CXF CXF 开发开发开发开发 4.2.14.2.14.2.14.2.1 开发环境 在这里简单说下注意事项:当你使用的是 JDK1.5 的时候你就必须要有 jaxws-api-2.0.jar 这个包的支持.如果使用的是 JDK1.6 就不用使用这个包了。因为1.6 里已经有了相关的实现 。 在JDK1.5 的开发环境下我们建议你使用 CXF2.0 开发版本比较好。 4.2.24.2.24.2.24.2.2 简单的 CXF CXF CXF CXF 应用 CXF 内置了 Jetty 应用服务器,当然也支持配置在别的 AppServer 上。我们不需要任何 配置,就可以让 CXF 使用 Jetty 来进行发布。 首先定义一个服务端的类: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第137页 共207 页 WebService 服务的提供者: Java 代码: /** *WebService服务端的实现类 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-16 */ @WebService publicpublicpublicpublicclassclassclassclassHelloWorld{ publicpublicpublicpublicStringsayHi(@WebParam(name="text")Stringtext){ returnreturnreturnreturn"Hello"+text; } } 服务端: Java 代码: /** *简单的WebService服务端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-16 */ publicpublicpublicpublicclassclassclassclassServerSimple{ protectedprotectedprotectedprotectedServerSimple()throwsthrowsthrowsthrowsException{ System.out.println("StartingServer"); HelloWorldhelloworldImpl=newnewnewnewHelloWorld(); Stringaddress="http://localhost:9000/helloWorld"; Endpoint.publish(address,helloworldImpl); } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args)throwsthrowsthrowsthrowsException{ newnewnewnewServerSimple(); System.out.println("Serverready..."); Thread.sleep(60*1000);//60秒后退出。 System.out.println("Serverexiting"); System.exit(0); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第138页 共207 页 } } 通过 CXF 的Endpoint类提供的静态方法,可以很容易的发布 WebService。Jetty默 认的是 9000端口。运行服务端,服务进程会等待 Client的请求 60秒。 客户端映射服务端服务的接口代码: Java代码: importimportimportimportjavax.jws.WebParam; importimportimportimportjavax.jws.WebService; /** *客户端映射WS服务提供的业务方法的接口,方法名、参数类型与WS服务相同即可。 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-16 */ @WebService publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceIHelloWorld{ publicpublicpublicpublicStringsayHi(@WebParam(name="text")Stringtext); } 客户端: Java代码: importimportimportimportorg.apache.cxf.jaxws.JaxWsProxyFactoryBean; /** *调用WebService的客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-16 */ publicpublicpublicpublicfinalfinalfinalfinalclassclassclassclassClient{ privateprivateprivateprivateClient(){ } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第139页 共207 页 /** *@param@param@param@paramargs */ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ JaxWsProxyFactoryBeanfactory=newnewnewnewJaxWsProxyFactoryBean(); factory.setServiceClass(IHelloWorld.classclassclassclass); factory.setAddress("http://localhost:9000/helloWorld"); IHelloWorldclient=(IHelloWorld)factory.create(); System.out.println("InvokesayHi()...."); System.out.println(client.sayHi(System.getProperty("user.name"))); System.exit(0); } } 客户端也没有什么复杂的地方,可以通过 JaxWsProxyFactoryBean获得虚拟远程服 务的业务对象的引用,像调用本地方法一样直接调用其方法。 运行结果: 服务端: StartingServer 2008-7-1710:20:52 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass 信息:CreatingService {http://server.simple.cxf.webservice/}HelloWorldServicefromclass webservice.cxf.simple.server.HelloWorld 2008-7-1710:20:53org.apache.cxf.endpoint.ServerImplinitDestination 信息:Settingtheserver'spublishaddresstobe http://localhost:9000/helloWorld 2008-07-1710:20:53.390::INFO:LoggingtoSTDERRvia org.mortbay.log.StdErrLog 2008-07-1710:20:53.421::INFO:jetty-6.1.9 2008-07-1710:20:53.702::INFO:Started SelectChannelConnector@0.0.0.0:9000 Serverready... 客户端: 2008-7-1710:23:35 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass 信息:CreatingService {http://client.simple.cxf.webservice/}IHelloWorldServicefromclass Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第140页 共207 页 webservice.cxf.simple.client.IHelloWorld InvokesayHi().... HelloQHL 4.2.34.2.34.2.34.2.3 CXF CXF CXF CXF 对请求的拦截处理 CXF 可以像 AXIS 的Handler 一样,在每个请求或响应的处理之前或者之后做一些处理 , 这些处理是通过 Interceptor 实现的。它及提供了很好的扩展性,让用户可以在服务被调用或 响应前后做很多事情,极大的降低了代码的耦合度,使服务提供者专注的提供服务,而不用 考虑其他的事情。我们来看看 Interceptor 是如何处理的。 服务端: Java 代码: importimportimportimportorg.apache.cxf.interceptor.LoggingInInterceptor; importimportimportimportorg.apache.cxf.interceptor.LoggingOutInterceptor; importimportimportimportorg.apache.cxf.jaxws.JaxWsServerFactoryBean; importimportimportimportwebservice.cxf.simple.server.HelloWorld; /** *带日志的WebService服务端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-16 */ publicpublicpublicpublicclassclassclassclassServer{ protectedprotectedprotectedprotectedServer()throwsthrowsthrowsthrowsException{ HelloWorldhelloworldImpl=newnewnewnewHelloWorld(); JaxWsServerFactoryBeansvrFactory=newnewnewnew JaxWsServerFactoryBean(); svrFactory.setServiceClass(HelloWorld.classclassclassclass); svrFactory.setAddress("http://localhost:9000/helloWorld"); svrFactory.setServiceBean(helloworldImpl); svrFactory.getInInterceptors().add(newnewnewnewLoggingInInterceptor()); svrFactory.getOutInterceptors().add(newnewnewnew LoggingOutInterceptor()); svrFactory.create(); } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第141页 共207 页 publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args)throwsthrowsthrowsthrowsException{ newnewnewnewServer(); System.out.println("Serverready..."); Thread.sleep(60*1000);//60秒后退出。 System.out.println("Serverexiting"); System.exit(0); } } 和上一个例子没有太大的差别,这里只是多了两句: svrFactory.getInInterceptors().add(newnewnewnewLoggingInInterceptor()); svrFactory.getOutInterceptors().add(newnewnewnewLoggingOutInterceptor()); 第一句表示在接收客户端发送请求的时候做日志处理,第二句标识在服务端响应客户端 请求的时候做日志处理。 同样客户端也可以做日志处理: 客户端: Java 代码: importimportimportimportorg.apache.cxf.interceptor.LoggingInInterceptor; importimportimportimportorg.apache.cxf.interceptor.LoggingOutInterceptor; importimportimportimportorg.apache.cxf.jaxws.JaxWsProxyFactoryBean; importimportimportimportwebservice.cxf.simple.client.IHelloWorld; /** *带输入输出拦截的WebService客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-16 */ publicpublicpublicpublicfinalfinalfinalfinalclassclassclassclassClient{ privateprivateprivateprivateClient(){ } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ JaxWsProxyFactoryBeanfactory=newnewnewnewJaxWsProxyFactoryBean(); factory.getInInterceptors().add(newnewnewnewLoggingInInterceptor()); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第142页 共207 页 factory.getOutInterceptors().add(newnewnewnewLoggingOutInterceptor()); factory.setServiceClass(IHelloWorld.classclassclassclass); factory.setAddress("http://localhost:9000/helloWorld"); IHelloWorldclient=(IHelloWorld)factory.create(); System.out.println("InvokesayHi()...."); System.out.println(client.sayHi(System.getProperty("user.name"))); System.exit(0); } } 这里也是增加了 2句代码,我们就不多说了,和之前讲的是一样的。 运行结果如下: 服务端: 2008-7-1710:46:05 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass 信息:CreatingService {http://server.simple.cxf.webservice/}HelloWorldServicefromclass webservice.cxf.simple.server.HelloWorld 2008-7-1710:46:05org.apache.cxf.endpoint.ServerImplinitDestination 信息:Settingtheserver'spublishaddresstobe http://localhost:9000/helloWorld 2008-07-1710:46:05.903::INFO:LoggingtoSTDERRvia org.mortbay.log.StdErrLog 2008-07-1710:46:05.919::INFO:jetty-6.1.9 2008-07-1710:46:05.012::INFO:Started SelectChannelConnector@0.0.0.0:9000 Serverready... 2008-7-1710:46:11org.apache.cxf.interceptor.LoggingInInterceptor logging 信息:InboundMessage ---------------------------- Encoding:UTF-8 Headers:{content-type=[text/xml;charset=UTF-8],connection=[keep- alive],transfer-encoding=[chunked],Host=[localhost:9000], SOAPAction=[""],User-Agent=[Java/1.6.0_06],Accept=[*],Pragma=[no- cache],Cache-Control=[no-cache]} Messages: Message: Payload:QHL -------------------------------------- 2008-7-1710:46:11 org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose 信息:OutboundMessage --------------------------- Encoding:UTF-8 Headers:{SOAPAction=[""]} Messages: Payload:Hello QHL -------------------------------------- 客户端: 2008-7-1710:46:10 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass 信息:CreatingService {http://client.simple.cxf.webservice/}IHelloWorldServicefromclass webservice.cxf.simple.client.IHelloWorld InvokesayHi().... 2008-7-1710:46:11 org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose 信息:OutboundMessage --------------------------- Encoding:UTF-8 Headers:{SOAPAction=[""],Accept=[*]} Messages: Payload:QHL -------------------------------------- 2008-7-1710:46:11org.apache.cxf.interceptor.LoggingInInterceptor logging Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第144页 共207 页 信息:InboundMessage ---------------------------- Encoding:UTF-8 Headers:{content-type=[text/xml;charset=utf-8],Content- Length=[223],SOAPAction=[""],Server=[Jetty(6.1.9)]} Messages: Message: Payload:Hello QHL -------------------------------------- HelloQHL 这里要讲两句的是 CXF 的所有拦截器都要实现 org.apache.cxf.interceptor.Interceptor 接 口,或者继承自 CXF 提供的抽象类。一般我们只要继承自 AbstractPhaseInterceptor 这个抽象类就行了。 当然,像 AXIS 可以处理多个 Handler 一样,CXF 也可以有多个 Interceptor 在请求或响 应之前、之后做处理,下面我们自己实现一个 Interceptor 看看效果。 自定义拦截器: Java 代码: /** *自定义的Interceptor拦截器 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-17 */ publicpublicpublicpublicclassclassclassclassMyInterceptorextendsextendsextendsextendsAbstractPhaseInterceptor { publicpublicpublicpublicMyInterceptor(Stringphase){ supersupersupersuper(phase); } publicpublicpublicpublicMyInterceptor(){ supersupersupersuper(Phase.RECEIVE); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第145页 共207 页 } /* *(non-Javadoc) * *@see org.apache.cxf.interceptor.Interceptor#handleFault(org.apache.cxf.mes sage.Message) */ publicpublicpublicpublicvoidvoidvoidvoidhandleFault(Messagearg0){ System.out.println("Error"); } /* *(non-Javadoc) * *@see org.apache.cxf.interceptor.Interceptor#handleMessage(org.apache.cxf.m essage.Message) */ publicpublicpublicpublicvoidvoidvoidvoidhandleMessage(Messagearg0)throwsthrowsthrowsthrowsFault{ System.out.println("Hello,ThisismyInterceptor."); } } 客户端代码: Java代码: importimportimportimportorg.apache.cxf.interceptor.LoggingInInterceptor; importimportimportimportorg.apache.cxf.interceptor.LoggingOutInterceptor; importimportimportimportorg.apache.cxf.jaxws.JaxWsProxyFactoryBean; importimportimportimportorg.apache.cxf.phase.Phase; importimportimportimportwebservice.cxf.interceptor.MyInterceptor; importimportimportimportwebservice.cxf.simple.client.IHelloWorld; /** *带输入输出拦截的WebService客户端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-16 */ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第146页 共207 页 publicpublicpublicpublicfinalfinalfinalfinalclassclassclassclassClient{ privateprivateprivateprivateClient(){ } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ JaxWsProxyFactoryBeanfactory=newnewnewnewJaxWsProxyFactoryBean(); factory.getInInterceptors().add(newnewnewnewLoggingInInterceptor()); factory.getInInterceptors().add(newnewnewnewMyInterceptor()); factory.getOutInterceptors().add(newnewnewnew MyInterceptor(Phase.SEND)); factory.getOutInterceptors().add(newnewnewnewLoggingOutInterceptor()); factory.setServiceClass(IHelloWorld.classclassclassclass); factory.setAddress("http://localhost:9000/helloWorld"); IHelloWorldclient=(IHelloWorld)factory.create(); System.out.println("InvokesayHi()...."); System.out.println(client.sayHi(System.getProperty("user.name"))); System.exit(0); } } 服务端代码: Java代码: importimportimportimportorg.apache.cxf.interceptor.LoggingInInterceptor; importimportimportimportorg.apache.cxf.interceptor.LoggingOutInterceptor; importimportimportimportorg.apache.cxf.jaxws.JaxWsServerFactoryBean; importimportimportimportorg.apache.cxf.phase.Phase; importimportimportimportwebservice.cxf.interceptor.MyInterceptor; importimportimportimportwebservice.cxf.simple.server.HelloWorld; /** *带日志的WebService服务端 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-16 */ publicpublicpublicpublicclassclassclassclassServer{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第147页 共207 页 protectedprotectedprotectedprotectedServer()throwsthrowsthrowsthrowsException{ HelloWorldhelloworldImpl=newnewnewnewHelloWorld(); JaxWsServerFactoryBeansvrFactory=newnewnewnew JaxWsServerFactoryBean(); svrFactory.setServiceClass(HelloWorld.classclassclassclass); svrFactory.setAddress("http://localhost:9000/helloWorld"); svrFactory.setServiceBean(helloworldImpl); svrFactory.getInInterceptors().add(newnewnewnewMyInterceptor()); svrFactory.getInInterceptors().add(newnewnewnewLoggingInInterceptor()); svrFactory.getOutInterceptors().add(newnewnewnew MyInterceptor(Phase.SEND)); svrFactory.getOutInterceptors().add(newnewnewnew LoggingOutInterceptor()); svrFactory.create(); } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args)throwsthrowsthrowsthrowsException{ newnewnewnewServer(); System.out.println("Serverready..."); Thread.sleep(60*1000);//60秒后退出。 System.out.println("Serverexiting"); System.exit(0); } } 这里有几点需要注意: � 我们的拦截器是不针对服务端还是客户端的。就是说一个实现可以用在两个地方。 � 继承 AbstractPhaseInterceptor至少要实现一个带参数的构造方法,我们实现了一个 带String类型参数的构造方法和一个默认无参构造方法。在无参构造方法中,有一句: supersupersupersuper(Phase.RECEIVE);其中Phase.RECEIVE表示这个实例处理的 InInterceptors过程,即便改实例被设置为 OutInterceptors,也不会起任何作用。 同理Phase.SEND是处理 OutInterceptors过程的,即便改实例被设置为 InInterceptors,也不会起任何作用。 4.2.44.2.44.2.44.2.4 CXF CXF CXF CXF 和Spring Spring Spring Spring 集成开发 下面介绍和目前比较流行的框架 Spring 的结合使用。 在集成之前先说下要涉及到的包,在CXF和Spring 结合需要有 4个包的支持就是 spring- beans.jar,spring-context.jar,spring-core.jar,spring-web.jar。这里提示一下这 4个包最好用 Spring 里的别用 CXF 的否则会出现版本冲突。 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第148页 共207 页 4.2.4.14.2.4.14.2.4.14.2.4.1 ListListListList、、、、MapMapMapMap、数组和自定义对象、数组和自定义对象、数组和自定义对象、数组和自定义对象 服务端的对象: Java 代码: /* *文件名: Address.java * *创建日期: 2008-7-11 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.cxf.selfobj.server.model; importimportimportimportjava.io.Serializable; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.List; importimportimportimportjava.util.Map; importimportimportimportjavax.xml.bind.annotation.XmlAccessType; importimportimportimportjavax.xml.bind.annotation.XmlAccessorType; importimportimportimportjavax.xml.bind.annotation.XmlType; /** *服务端的自定义类型 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ @XmlType(name="ServerAddress") @XmlAccessorType(XmlAccessType.FIELD) publicpublicpublicpublicclassclassclassclassAddressimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=5182870829593983607L; privateprivateprivateprivateIntegeridentifier; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第149页 共207 页 /**地址 */ privateprivateprivateprivateStringaddress; /**城市 */ privateprivateprivateprivateStringcity; /**省份 */ privateprivateprivateprivateStringprovince; /**国家 */ privateprivateprivateprivateStringcountry; /**邮编 */ privateprivateprivateprivateStringpostalCode; privateprivateprivateprivateString[]array; privateprivateprivateprivateListlist; privateprivateprivateprivateMapmap; privateprivateprivateprivatebooleanbooleanbooleanbooleanisExist; privateprivateprivateprivateInnerClassinnC; @XmlType(name="ServerInnerClass") @XmlAccessorType(XmlAccessType.FIELD) publicpublicpublicpublicstaticstaticstaticstaticclassclassclassclassInnerClassimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=-2330738090948448510L; privateprivateprivateprivateStringinnerName="staticInnerClass"; publicpublicpublicpublicInnerClass(){}; publicpublicpublicpublicInnerClass(StringinnerName){ supersupersupersuper(); thisthisthisthis.innerName=innerName; } publicpublicpublicpublicStringgetInnerName(){ returnreturnreturnreturninnerName; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第150页 共207 页 publicpublicpublicpublicvoidvoidvoidvoidsetInnerName(StringinnerName){ thisthisthisthis.innerName=innerName; } } publicpublicpublicpublicAddress(){ list=newnewnewnewArrayList(); list.add(1); list.add(2); list.add(3); map=newnewnewnewHashMap(); map.put(1,newnewnewnewInnerClass("A")); map.put(2,newnewnewnewInnerClass("B")); map.put(3,newnewnewnewInnerClass("C")); innC=newnewnewnewInnerClass(); innC.setInnerName("服务端:Address.InnerClass"); } @Override publicpublicpublicpublicStringtoString(){ StringreturnStr=supersupersupersuper.toString() +"id号:"+getIdentifier() +"address:"+getAddress() +"city:"+getCity() +"country:"+getCountry() +"postalCode:"+getPostalCode() +"province:"+getProvince() +"array:"+getArray()[0] +"list:"+getList() +"map:"+getMap() +"isExist:"+isExist() +"innerClass.name:"+getInnC().getInnerName(); returnreturnreturnreturnreturnStr; } publicpublicpublicpublicInnerClassgetInnC(){ returnreturnreturnreturninnC; } publicpublicpublicpublicvoidvoidvoidvoidsetInnC(InnerClassinnC){ thisthisthisthis.innC=innC; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第151页 共207 页 publicpublicpublicpublicIntegergetIdentifier(){ returnreturnreturnreturnidentifier; } publicpublicpublicpublicvoidvoidvoidvoidsetIdentifier(Integeridentifier){ thisthisthisthis.identifier=identifier; } publicpublicpublicpublicStringgetAddress(){ returnreturnreturnreturnaddress; } publicpublicpublicpublicvoidvoidvoidvoidsetAddress(Stringaddress){ thisthisthisthis.address=address; } publicpublicpublicpublicStringgetCity(){ returnreturnreturnreturncity; } publicpublicpublicpublicvoidvoidvoidvoidsetCity(Stringcity){ thisthisthisthis.city=city; } publicpublicpublicpublicStringgetProvince(){ returnreturnreturnreturnprovince; } publicpublicpublicpublicvoidvoidvoidvoidsetProvince(Stringprovince){ thisthisthisthis.province=province; } publicpublicpublicpublicStringgetCountry(){ returnreturnreturnreturncountry; } publicpublicpublicpublicvoidvoidvoidvoidsetCountry(Stringcountry){ thisthisthisthis.country=country; } publicpublicpublicpublicStringgetPostalCode(){ returnreturnreturnreturnpostalCode; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第152页 共207 页 publicpublicpublicpublicvoidvoidvoidvoidsetPostalCode(StringpostalCode){ thisthisthisthis.postalCode=postalCode; } publicpublicpublicpublicString[]getArray(){ returnreturnreturnreturnarray; } publicpublicpublicpublicvoidvoidvoidvoidsetArray(String[]array){ thisthisthisthis.array=array; } publicpublicpublicpublicbooleanbooleanbooleanbooleanisExist(){ returnreturnreturnreturnisExist; } publicpublicpublicpublicvoidvoidvoidvoidsetExist(booleanbooleanbooleanbooleanisExist){ thisthisthisthis.isExist=isExist; } publicpublicpublicpublicListgetList(){ returnreturnreturnreturnlist; } publicpublicpublicpublicvoidvoidvoidvoidsetList(Listlist){ thisthisthisthis.list=list; } publicpublicpublicpublicMapgetMap(){ returnreturnreturnreturnmap; } publicpublicpublicpublicvoidvoidvoidvoidsetMap(Mapmap){ thisthisthisthis.map=map; } } 服务端的方法: Java 代码: /* *文件名: AddressManager.java * Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第153页 共207 页 *创建日期: 2008-7-11 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.cxf.selfobj.server; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.List; importimportimportimportjava.util.Map; importimportimportimportjavax.jws.WebService; importimportimportimportjavax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; importimportimportimportwebservice.cxf.selfobj.server.model.Address; /** *提供复杂对象的WebService业务 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ @WebService publicpublicpublicpublicclassclassclassclassAddressManager{ privateprivateprivateprivateintintintintrequestCount=0; publicpublicpublicpublicList
getAddressList(){ requestCount++; System.out.println("requestCount="+requestCount); List
returnList=newnewnewnewArrayList
(); Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第154页 共207 页 address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); returnList.add(address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); returnList.add(address); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); returnreturnreturnreturnreturnList; } publicpublicpublicpublicList
setAddressList(List
list){ requestCount++; System.out.println("requestCount="+requestCount); returnreturnreturnreturnlist; } } 开始配置 Spring 的文件 applicationContext.xml : 在这里主要要注意红色的地方。 配置相应的 Web.xml文件: contextConfigLocation Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第156页 共207 页 classpath:applicationContext.xml org.springframework.web.context.ContextLoaderListener org.springframework.web.util.IntrospectorCleanupListener CXFServlet org.apache.cxf.transport.servlet.CXFServlet 1 CXFServlet /* 客户端对象: Java 代码: /* *文件名: Address.java * *创建日期: 2008-7-11 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.cxf.selfobj.client.model; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第157页 共207 页 importimportimportimportjava.io.Serializable; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.HashMap; importimportimportimportjava.util.List; importimportimportimportjava.util.Map; importimportimportimportjavax.xml.bind.annotation.XmlAccessType; importimportimportimportjavax.xml.bind.annotation.XmlAccessorType; importimportimportimportjavax.xml.bind.annotation.XmlType; /** *客户端的自定义类型 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-11 */ @XmlType(name="ClientAddress") @XmlAccessorType(XmlAccessType.FIELD) publicpublicpublicpublicclassclassclassclassAddressimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=5182870829593983607L; privateprivateprivateprivateIntegeridentifier; /**地址 */ privateprivateprivateprivateStringaddress; /**城市 */ privateprivateprivateprivateStringcity; /**省份 */ privateprivateprivateprivateStringprovince; /**国家 */ privateprivateprivateprivateStringcountry; /**邮编 */ privateprivateprivateprivateStringpostalCode; privateprivateprivateprivateString[]array; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第158页 共207 页 privateprivateprivateprivateListlist; privateprivateprivateprivateMapmap; privateprivateprivateprivatebooleanbooleanbooleanbooleanisExist; privateprivateprivateprivateInnerClassinnC; @XmlType(name="ClientInnerClass") @XmlAccessorType(XmlAccessType.FIELD) publicpublicpublicpublicstaticstaticstaticstaticclassclassclassclassInnerClassimplementsimplementsimplementsimplementsSerializable{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID=-2330738090948448510L; publicpublicpublicpublicInnerClass(){}; publicpublicpublicpublicInnerClass(StringinnerName){ supersupersupersuper(); thisthisthisthis.innerName=innerName; } privateprivateprivateprivateStringinnerName="staticInnerClass"; publicpublicpublicpublicStringgetInnerName(){ returnreturnreturnreturninnerName; } publicpublicpublicpublicvoidvoidvoidvoidsetInnerName(StringinnerName){ thisthisthisthis.innerName=innerName; } } publicpublicpublicpublicAddress(){ list=newnewnewnewArrayList(); list.add(1); list.add(2); list.add(3); map=newnewnewnewHashMap(); map.put(1,newnewnewnewInnerClass("A")); map.put(2,newnewnewnewInnerClass("B")); map.put(3,newnewnewnewInnerClass("C")); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第159页 共207 页 innC=newnewnewnewInnerClass(); innC.setInnerName("客户端:Address.InnerClass"); } @Override publicpublicpublicpublicStringtoString(){ StringreturnStr=supersupersupersuper.toString() +"id号:"+getIdentifier() +"address:"+getAddress() +"city:"+getCity() +"country:"+getCountry() +"postalCode:"+getPostalCode() +"province:"+getProvince() +"array:"+getArray()[0] +"list:"+getList() +"map:"+getMap() +"isExist:"+isExist() +"innerClass.name:"+getInnC().getInnerName(); returnreturnreturnreturnreturnStr; } publicpublicpublicpublicInnerClassgetInnC(){ returnreturnreturnreturninnC; } publicpublicpublicpublicvoidvoidvoidvoidsetInnC(InnerClassinnC){ thisthisthisthis.innC=innC; } publicpublicpublicpublicIntegergetIdentifier(){ returnreturnreturnreturnidentifier; } publicpublicpublicpublicvoidvoidvoidvoidsetIdentifier(Integeridentifier){ thisthisthisthis.identifier=identifier; } publicpublicpublicpublicStringgetAddress(){ returnreturnreturnreturnaddress; } publicpublicpublicpublicvoidvoidvoidvoidsetAddress(Stringaddress){ thisthisthisthis.address=address; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第160页 共207 页 publicpublicpublicpublicStringgetCity(){ returnreturnreturnreturncity; } publicpublicpublicpublicvoidvoidvoidvoidsetCity(Stringcity){ thisthisthisthis.city=city; } publicpublicpublicpublicStringgetProvince(){ returnreturnreturnreturnprovince; } publicpublicpublicpublicvoidvoidvoidvoidsetProvince(Stringprovince){ thisthisthisthis.province=province; } publicpublicpublicpublicStringgetCountry(){ returnreturnreturnreturncountry; } publicpublicpublicpublicvoidvoidvoidvoidsetCountry(Stringcountry){ thisthisthisthis.country=country; } publicpublicpublicpublicStringgetPostalCode(){ returnreturnreturnreturnpostalCode; } publicpublicpublicpublicvoidvoidvoidvoidsetPostalCode(StringpostalCode){ thisthisthisthis.postalCode=postalCode; } publicpublicpublicpublicString[]getArray(){ returnreturnreturnreturnarray; } publicpublicpublicpublicvoidvoidvoidvoidsetArray(String[]array){ thisthisthisthis.array=array; } publicpublicpublicpublicbooleanbooleanbooleanbooleanisExist(){ returnreturnreturnreturnisExist; } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第161页 共207 页 publicpublicpublicpublicvoidvoidvoidvoidsetExist(booleanbooleanbooleanbooleanisExist){ thisthisthisthis.isExist=isExist; } publicpublicpublicpublicListgetList(){ returnreturnreturnreturnlist; } publicpublicpublicpublicvoidvoidvoidvoidsetList(Listlist){ thisthisthisthis.list=list; } publicpublicpublicpublicMapgetMap(){ returnreturnreturnreturnmap; } publicpublicpublicpublicvoidvoidvoidvoidsetMap(Mapmap){ thisthisthisthis.map=map; } } 客户端接口: Java 代码: /* *文件名: IClientAddressManager.java * *创建日期: 2008-7-17 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.cxf.selfobj.client; importimportimportimportjava.util.List; importimportimportimportjava.util.Map; importimportimportimportjavax.jws.WebService; importimportimportimportwebservice.cxf.selfobj.client.model.Address; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第162页 共207 页 /** *本地实现一个Remote接口,其中包含远程WS的方法(同名、同返回类型、同参数类型), *则通过Service可以获得一个对远程WS对象的引用。用该引用可以直接像调用本地方法一样调用远程 方法。 *服务端不用做任何设置和调整。 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-17 */ @WebService publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceIClientAddressManager{ publicpublicpublicpublicList
getAddressList(); publicpublicpublicpublicList
setAddressList(List
list); } 客户端 JAVA类: /* *文件名: Client.java * *创建日期: 2008-7-17 * *Copyright(C)2008,byAlong. * *原始作者:Along * */ packagepackagepackagepackagewebservice.cxf.selfobj.client; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.Iterator; importimportimportimportjava.util.List; importimportimportimportorg.apache.cxf.interceptor.LoggingInInterceptor; importimportimportimportorg.apache.cxf.interceptor.LoggingOutInterceptor; importimportimportimportorg.apache.cxf.jaxws.JaxWsProxyFactoryBean; importimportimportimportwebservice.cxf.selfobj.client.model.Address; /** *WebService客户端 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第163页 共207 页 * *@author@author@author@authorAlong * *@version@version@version@version$Revision$ * *@since@since@since@since2008-7-17 */ publicpublicpublicpublicclassclassclassclassClient{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidgetServerList(){ JaxWsProxyFactoryBeanfactory=newnewnewnewJaxWsProxyFactoryBean(); factory.getInInterceptors().add(newnewnewnewLoggingInInterceptor()); factory.getOutInterceptors().add(newnewnewnewLoggingOutInterceptor()); factory.setServiceClass(IClientAddressManager.classclassclassclass); factory.setAddress("http://127.0.0.1:8089/mycxf/Address"); IClientAddressManagerclient= (IClientAddressManager)factory.create(); List
list=(ArrayList
)client.getAddressList(); System.out.println("getServerListbegin---------------"); System.out.println("Listsize:"+list.size()); forforforfor(Iterator
iter=list.iterator();iter.hasNext();){ Addressaddress=iter.next(); System.out.println(address); } System.out.println("getServerListend---------------"); } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidsetServerList(){ JaxWsProxyFactoryBeanfactory=newnewnewnewJaxWsProxyFactoryBean(); factory.getInInterceptors().add(newnewnewnewLoggingInInterceptor()); factory.getOutInterceptors().add(newnewnewnewLoggingOutInterceptor()); factory.setServiceClass(IClientAddressManager.classclassclassclass); factory.setAddress("http://127.0.0.1:8089/mycxf/Address"); IClientAddressManagerclient= (IClientAddressManager)factory.create(); List
list=newnewnewnewArrayList
(); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第164页 共207 页 Addressaddress=newnewnewnewAddress(); address.setIdentifier(1); address.setAddress("Haidian"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(falsefalsefalsefalse); address.setArray(newnewnewnewString[]{"1","2","3"}); list.add(address); address=newnewnewnewAddress(); address.setIdentifier(2); address.setAddress("Chaoyang"); address.setCity("BeiJing"); address.setCountry("China"); address.setPostalCode("100081"); address.setProvince("Beijing"); address.setExist(truetruetruetrue); address.setArray(newnewnewnewString[]{"A","B","C"}); list.add(address); List
returnList=client.setAddressList(list); System.out.println("Listsize:"+returnList.size()); forforforfor(Iterator
iter=returnList.iterator();iter.hasNext();) { address=iter.next(); System.out.println(address); } } publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ getServerList(); setServerList(); } } 输出结果: 客户端: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第165页 共207 页 getServerListbegin--------------- Listsize:2 webservice.cxf.selfobj.client.model.Address@d480eaid号:1address: Haidiancity:BeiJingcountry:ChinapostalCode:100081province:Beijing array:1list:[1,2,3]map: {2=webservice.cxf.selfobj.client.model.Address$InnerClass@15b8520, 1=webservice.cxf.selfobj.client.model.Address$InnerClass@18105e8, 3=webservice.cxf.selfobj.client.model.Address$InnerClass@1aacd5f} isExist:falseinnerClass.name:服务端:Address.InnerClass webservice.cxf.selfobj.client.model.Address@913dc1id号:2address: Chaoyangcity:BeiJingcountry:ChinapostalCode:100081province: Beijingarray:Alist:[1,2,3]map: {2=webservice.cxf.selfobj.client.model.Address$InnerClass@16d8196, 1=webservice.cxf.selfobj.client.model.Address$InnerClass@56b93a, 3=webservice.cxf.selfobj.client.model.Address$InnerClass@19abd2b} isExist:trueinnerClass.name:服务端:Address.InnerClass getServerListend--------------- Listsize:2 webservice.cxf.selfobj.client.model.Address@edbe39id号:1address: Haidiancity:BeiJingcountry:ChinapostalCode:100081province:Beijing array:1list:[1,2,3]map: {2=webservice.cxf.selfobj.client.model.Address$InnerClass@639bf1, 1=webservice.cxf.selfobj.client.model.Address$InnerClass@1931579, 3=webservice.cxf.selfobj.client.model.Address$InnerClass@166bfd8} isExist:falseinnerClass.name:客户端:Address.InnerClass webservice.cxf.selfobj.client.model.Address@bd09e8id号:2address: Chaoyangcity:BeiJingcountry:ChinapostalCode:100081province: Beijingarray:Alist:[1,2,3]map: {2=webservice.cxf.selfobj.client.model.Address$InnerClass@d58ce2, 1=webservice.cxf.selfobj.client.model.Address$InnerClass@14627a, 3=webservice.cxf.selfobj.client.model.Address$InnerClass@4d41e2} isExist:trueinnerClass.name:客户端:Address.InnerClass 表示你已经成功,但是在这里说下关于直接通过方法返回 MAP 的时候不行,我们也试验过 CXF 自带的 DEMO 他上面是说使用对 XmlAdapter 的集成来实现但是没有成功。希望有研 究的朋友能够加入本群或者联系我和 Along 我们一起讨论下。 Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第166页 共207 页 5555....整合篇整合篇整合篇整合篇 5.1 5.1 5.1 5.1 简介简介简介简介 这部分主要讲解怎么使用一个 ws 来进行开发,这里主要拿 axis 为例,因为它的使用比较多 。 然后结合在群里发出的错误和需求做一个详细说明。 为了让大家在实际中使用更方便,这里我们会尽量使用代码来对比说明。关于源码我们会开 放出来一起研究。 5.25.25.25.2 整合使用整合使用整合使用整合使用 这个列子主要用 spring+hibernate+axis 来实现的,为了使代码简单我们只做了一个数据表主 要是为了实现简单。 在WS里主要就是服务端和客户端,一般客户端比较容易编写通过定义好的 WSDL 在这里 我们就不做讲解了,现在主要讲解服务端,我看群里的哥们并不是把 AXIS 集成到自己的项 目里所以我们先说下把 AXIS 集成到自己的项目中。 配置 Web.xml 代码如下: AXIS-Integrate org.apache.axis.transport.http.AxisHTTPSessionListener AxisServlet Apache-AxisServlet org.apache.axis.transport.http.AxisServlet AdminServlet Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第167页 共207 页 AxisAdminServlet org.apache.axis.transport.http.AdminServlet 100 SOAPMonitorService SOAPMonitorService org.apache.axis.monitor.SOAPMonitorService SOAPMonitorPort 5001 100 AxisServlet /servlet/AxisServlet AxisServlet *.jws AxisServlet /services/* SOAPMonitorService /SOAPMonitor 5 wsdl text/xml xsd text/xml /servlet/AxisServlet 这样你的项目集成了 AXIS 的功能,但是这里要注意一点就是 SOAPAction 在我们和.net 通 讯的时候出现了问题,在 axis 会对这个节点进行检验如果这个节点为空就会抛出异常。所 以大家要是想做兼容就要修改自己做一个 AxisServlet类 其实这个很简单就是去掉对 SOAPAction 的校验,来看代码: /* *文件名: AxisServlet.java * *创建日期: 2009-3-31 * *Copyright(C)2009,byxiaozhi. * *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第169页 共207 页 importimportimportimportjava.io.File; importimportimportimportjava.io.IOException; importimportimportimportjava.io.PrintWriter; importimportimportimportjava.lang.reflect.InvocationTargetException; importimportimportimportjava.lang.reflect.Method; importimportimportimportjava.net.HttpURLConnection; importimportimportimportjava.util.ArrayList; importimportimportimportjava.util.Enumeration; importimportimportimportjava.util.Iterator; importimportimportimportjavax.servlet.ServletContext; importimportimportimportjavax.servlet.ServletException; importimportimportimportjavax.servlet.http.HttpServletRequest; importimportimportimportjavax.servlet.http.HttpServletResponse; importimportimportimportjavax.servlet.http.HttpUtils; importimportimportimportjavax.xml.soap.MimeHeader; importimportimportimportjavax.xml.soap.MimeHeaders; importimportimportimportjavax.xml.soap.SOAPException; importimportimportimportjavax.xml.soap.SOAPMessage; importimportimportimportorg.apache.axis.AxisEngine; importimportimportimportorg.apache.axis.AxisFault; importimportimportimportorg.apache.axis.ConfigurationException; importimportimportimportorg.apache.axis.Constants; importimportimportimportorg.apache.axis.Handler; importimportimportimportorg.apache.axis.Message; importimportimportimportorg.apache.axis.MessageContext; importimportimportimportorg.apache.axis.SimpleTargetedChain; importimportimportimportorg.apache.axis.components.logger.LogFactory; importimportimportimportorg.apache.axis.description.OperationDesc; importimportimportimportorg.apache.axis.description.ServiceDesc; importimportimportimportorg.apache.axis.handlers.soap.SOAPService; importimportimportimportorg.apache.axis.management.ServiceAdmin; importimportimportimportorg.apache.axis.security.servlet.ServletSecurityProvider; importimportimportimportorg.apache.axis.transport.http.AxisHttpSession; importimportimportimportorg.apache.axis.transport.http.AxisServletBase; importimportimportimportorg.apache.axis.transport.http.FilterPrintWriter; importimportimportimportorg.apache.axis.transport.http.HTTPConstants; importimportimportimportorg.apache.axis.transport.http.HTTPTransport; importimportimportimportorg.apache.axis.transport.http.ServletEndpointContextImpl; importimportimportimportorg.apache.axis.utils.JavaUtils; importimportimportimportorg.apache.axis.utils.Messages; importimportimportimportorg.apache.axis.utils.XMLUtils; importimportimportimportorg.apache.commons.logging.Log; importimportimportimportorg.w3c.dom.Element; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第170页 共207 页 /** *作为WS服务端的发布类。兼容了.NET去掉了SOAPACTION的检验 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2009-3-31 */ @SuppressWarnings( {"unchecked","deprecation"}) publicpublicpublicpublicclassclassclassclassAxisServletextendsextendsextendsextendsAxisServletBase{ privateprivateprivateprivatestaticstaticstaticstaticfinalfinalfinalfinallonglonglonglongserialVersionUID= 2925997325383360187L; protectedprotectedprotectedprotectedstaticstaticstaticstaticLoglog= LogFactory.getLog(AxisServlet.classclassclassclass.getName()); /** *thislogisfortiming */ privateprivateprivateprivatestaticstaticstaticstaticLogtlog= LogFactory.getLog(Constants.TIME_LOG_CATEGORY); /** *aseparatelogforexceptionsletsusersroutethem differentlyfrom *generallowleveldebuginfo */ privateprivateprivateprivatestaticstaticstaticstaticLogexceptionLog=LogFactory .getLog(Constants.EXCEPTION_LOG_CATEGORY); publicpublicpublicpublicstaticstaticstaticstaticfinalfinalfinalfinalStringINIT_PROPERTY_TRANSPORT_NAME= "transport.name"; publicpublicpublicpublicstaticstaticstaticstaticfinalfinalfinalfinalStringINIT_PROPERTY_USE_SECURITY="use- servlet-security"; publicpublicpublicpublicstaticstaticstaticstaticfinalfinalfinalfinalStringINIT_PROPERTY_ENABLE_LIST= "axis.enableListQuery"; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第171页 共207 页 publicpublicpublicpublicstaticstaticstaticstaticfinalfinalfinalfinalStringINIT_PROPERTY_JWS_CLASS_DIR= "axis.jws.servletClassDir"; //Thiswillturnoffthelistofavailableservices publicpublicpublicpublicstaticstaticstaticstaticfinalfinalfinalfinalStringINIT_PROPERTY_DISABLE_SERVICES_LIST ="axis.disableServiceList"; //Locationoftheservicesasdefinedbytheservlet-mapping inweb.xml publicpublicpublicpublicstaticstaticstaticstaticfinalfinalfinalfinalStringINIT_PROPERTY_SERVICES_PATH= "axis.servicesPath"; //Thesehavedefaultvalues. privateprivateprivateprivateStringtransportName; privateprivateprivateprivateHandlertransport; privateprivateprivateprivateServletSecurityProvidersecurityProvider=nullnullnullnull; privateprivateprivateprivateStringservicesPath; /** *cacheofloggingdebugoption;onlyevaluatedatinittime. Sonodynamic *switchingofloggingoptionswiththisservlet. */ privateprivateprivateprivatestaticstaticstaticstaticbooleanbooleanbooleanbooleanisDebug=falsefalsefalsefalse; /** *Shouldweenablethe"?list"functionalityonGETs?(offby default *becausedeploymentinformationisapotentialsecurityhole) */ privateprivateprivateprivatebooleanbooleanbooleanbooleanenableList=falsefalsefalsefalse; /** *Shouldweturnoffthelistofserviceswhenwereceivea GETatthe *servletroot? */ privateprivateprivateprivatebooleanbooleanbooleanbooleandisableServicesList=falsefalsefalsefalse; /** *CachedpathtoJWSoutputdirectory Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第172页 共207 页 */ privateprivateprivateprivateStringjwsClassDir=nullnullnullnull; protectedprotectedprotectedprotectedStringgetJWSClassDir(){ returnreturnreturnreturnjwsClassDir; } /** *createanewservletinstance */ publicpublicpublicpublicAxisServlet(){ } /** *Initializationmethod. */ publicpublicpublicpublicvoidvoidvoidvoidinit()throwsthrowsthrowsthrowsjavax.servlet.ServletException{ supersupersupersuper.init(); ServletContextcontext= getServletConfig().getServletContext(); isDebug=log.isDebugEnabled(); ifififif(isDebug){ log.debug("Inservletinit"); } transportName=getOption(context, INIT_PROPERTY_TRANSPORT_NAME, HTTPTransport.DEFAULT_TRANSPORT_NAME); ifififif(JavaUtils.isTrueExplicitly(getOption(context, INIT_PROPERTY_USE_SECURITY,nullnullnullnull))){ securityProvider=newnewnewnewServletSecurityProvider(); } enableList=JavaUtils.isTrueExplicitly(getOption(context, INIT_PROPERTY_ENABLE_LIST,nullnullnullnull)); jwsClassDir=getOption(context, INIT_PROPERTY_JWS_CLASS_DIR,nullnullnullnull); disableServicesList=JavaUtils.isTrue(getOption(context, INIT_PROPERTY_DISABLE_SERVICES_LIST,"false")); servicesPath=getOption(context, INIT_PROPERTY_SERVICES_PATH, "/service/"); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第173页 共207 页 /** *ThereareDEFINATEproblemshereifgetHomeDirand/or *getDefaultJWSClassDirreturnnull(astheycouldwith WebLogic).This *needstobereexaminedinthefuture,butthisshould fixanyNPE's *inthemeantime. */ ifififif(jwsClassDir!=nullnullnullnull){ ifififif(getHomeDir()!=nullnullnullnull){ jwsClassDir=getHomeDir()+jwsClassDir; } } elseelseelseelse{ jwsClassDir=getDefaultJWSClassDir(); } initQueryStringHandlers(); //Setuptheserviceadmin trytrytrytry{ ServiceAdmin.setEngine(thisthisthisthis.getEngine(), context.getServerInfo()); } catchcatchcatchcatch(AxisFaultaf){ exceptionLog.info("ExceptionsettingAxisEngineon ServiceAdmin" +af); } } /** *ProcessGETrequests.Thisincludeshandoffofpseudo-SOAP requests * *@param@param@param@paramrequest * requestin *@param@param@param@paramresponse * requestout *@throws@throws@throws@throwsServletException *@throws@throws@throws@throwsIOException */ publicpublicpublicpublicvoidvoidvoidvoiddoGet(HttpServletRequestrequest, Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第174页 共207 页 HttpServletResponseresponse) throwsthrowsthrowsthrowsServletException,IOException{ ifififif(isDebug){ log.debug("Enter:doGet()"); } PrintWriterwriter=newnewnewnewFilterPrintWriter(response); trytrytrytry{ AxisEngineengine=getEngine(); ServletContextservletContext=getServletConfig() .getServletContext(); StringpathInfo=request.getPathInfo(); Stringrealpath=servletContext.getRealPath(request .getServletPath()); ifififif(realpath==nullnullnullnull){ realpath=request.getServletPath(); } //JWSpagesarespecial;theyaretheservletpathand there //isnopathinfo...wemapthepathinfototheservlet pathtokeep //ithappy booleanbooleanbooleanbooleanisJWSPage= request.getRequestURI().endsWith(".jws"); ifififif(isJWSPage){ pathInfo=request.getServletPath(); } //Trytoexecuteaquerystringpluginandreturnupon success. ifififif(processQuery(request,response,writer)==truetruetruetrue){ returnreturnreturnreturn; } booleanbooleanbooleanbooleanhasNoPath=(pathInfo==nullnullnullnull|| pathInfo.equals("")); ifififif(!disableServicesList){ ifififif(hasNoPath){ //Iftheuserrequestedtheservlet(i.e. ///axis/servlet/AxisServlet) Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第175页 共207 页 //withnoservicename,presenttheuserwitha listof //deployed //servicestobehelpful //Don'tdothisifhasbeenturnedoff reportAvailableServices(response,writer, request); } elseelseelseelseifififif(realpath!=nullnullnullnull){ //Wehaveapathname,sonowweperformWSDLor list //operations //getmessagecontextw/variouspropertiesset MessageContextmsgContext= createMessageContext(engine, request,response); //NOTE:HttpUtils.getRequestURLhasbeen deprecated. //ThislineSHOULDbe: //Stringurl=req.getRequestURL().toString() //HOWEVER!!!!DON'TREPLACEIT!There'sabugin //req.getRequestURLthatisnotin HttpUtils.getRequestURL //req.getRequestURLreturns"localhost"inthe remote //scenarioratherthantheactualhostname. // //Butmoreimportantly,getRequestURL()isa servlet2.3 //APIandtosupportservlet2.2(akaWebSphere 4) //weneedtoleavethisinforawhilelonger. tomj //10/14/2004 // Stringurl= HttpUtils.getRequestURL(request).toString(); msgContext.setProperty(MessageContext.TRANS_URL, url); //Seeifwecanlocatethedesiredservice.If Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第176页 共207 页 we //can't,returna404NotFound.Otherwise,just //printtheplaceholdermessage. StringserviceName; ifififif(pathInfo.startsWith("/")){ serviceName=pathInfo.substring(1); } elseelseelseelse{ serviceName=pathInfo; } SOAPServices=engine.getService(serviceName); ifififif(s==nullnullnullnull){ //noservice:reportit ifififif(isJWSPage){ reportCantGetJWSService(request,response, writer); } elseelseelseelse{ reportCantGetAxisService(request,response, writer); } } elseelseelseelse{ //printasnippetofserviceinfo. reportServiceInfo(response,writer,s, serviceName); } } } elseelseelseelse{ response.setContentType("text/html;charset=utf-8"); writer.println("

AxisHTTPServlet

"); writer.println(Messages.getMessage("reachedServlet00")); writer.println("

" +Messages.getMessage("transportName00", "" +transportName+"")); writer.println(""); } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第177页 共207 页 } catchcatchcatchcatch(AxisFaultfault){ reportTroubleInGet(fault,response,writer); } catchcatchcatchcatch(Exceptione){ reportTroubleInGet(e,response,writer); } finallyfinallyfinallyfinally{ writer.close(); ifififif(isDebug){ log.debug("Exit:doGet()"); } } } /** *whenwegetanexceptionoranaxisfaultinaGET,we handleitalmost *identically:wego'somethingwentwrong',settheresponse codeto500 *andthendumpinfo.Butwedumpdifferentinfoforanaxis faultor *subclassthereof. * *@param@param@param@paramexception * whatwentwrong *@param@param@param@paramresponse * currentresponse *@param@param@param@paramwriter * openwritertoresponse */ privateprivateprivateprivatevoidvoidvoidvoidreportTroubleInGet(Throwableexception, HttpServletResponseresponse,PrintWriterwriter){ response.setContentType("text/html;charset=utf-8"); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERRO R); writer.println("

"+Messages.getMessage("error00")+ "

"); writer .println("

"+ Messages.getMessage("somethingWrong00") +"

"); ifififif(exceptioninstanceofinstanceofinstanceofinstanceofAxisFault){ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第178页 共207 页 AxisFaultfault=(AxisFault)exception; processAxisFault(fault); writeFault(writer,fault); } elseelseelseelse{ logException(exception); writer.println("
Exception-"+exception+  "
"); //devsystemsonlygivefaultdumps ifififif(isDevelopment()){ writer.println(JavaUtils.stackToString(exception)); } writer.println("
"); } } /** *routinecalledwheneveranaxisfaultiscaught;wherethey arelogged *andanyotherbusiness.Themethodmaymodifythefaultin theprocess * *@param@param@param@paramfault * whatwentwrong. */ protectedprotectedprotectedprotectedvoidvoidvoidvoidprocessAxisFault(AxisFaultfault){ //logthefault ElementruntimeException=fault .lookupFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTIO N); ifififif(runtimeException!=nullnullnullnull){ exceptionLog.info(Messages.getMessage("axisFault00"), fault); //stripruntimedetails fault .removeFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTIO N); } elseelseelseelseifififif(exceptionLog.isDebugEnabled()){ exceptionLog.debug(Messages.getMessage("axisFault00"), fault); } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第179页 共207 页 //devsystemsonlygivefaultdumps ifififif(!isDevelopment()){ //stripoutthestacktrace fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_STACKTRACE) ; } } /** *loganyexceptiontoouroutputlog,atourchosenlevel * *@param@param@param@parame * whatwentwrong */ protectedprotectedprotectedprotectedvoidvoidvoidvoidlogException(Throwablee){ exceptionLog.info(Messages.getMessage("exception00"),e); } /** *thismethodwritesafaultouttoanHTMLstream.This includesescaping *thestringstodefendagainstcross-sitescriptingattacks * *@param@param@param@paramwriter *@param@param@param@paramaxisFault */ privateprivateprivateprivatevoidvoidvoidvoidwriteFault(PrintWriterwriter,AxisFault axisFault){ StringlocalizedMessage= XMLUtils.xmlEncodeString(axisFault .getLocalizedMessage()); writer.println("
Fault-"+localizedMessage+"
"); writer.println(axisFault.dumpToString()); writer.println("
"); } /** *printasnippetofserviceinfo. * *@param@param@param@paramservice * service *@param@param@param@paramwriter * outputchannel Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第180页 共207 页 *@param@param@param@paramserviceName * wheretoputstuff */ protectedprotectedprotectedprotectedvoidvoidvoidvoidreportServiceInfo(HttpServletResponseresponse, PrintWriterwriter,SOAPServiceservice,String serviceName){ response.setContentType("text/html;charset=utf-8"); writer.println("

"+service.getName()+"

"); writer.println("

"+Messages.getMessage("axisService00") +"

"); writer.println(""+Messages.getMessage("perhaps00")+ ""); } /** *reportthatwehavenoWSDL * *Thismethodwasmovedtothequerystringhandler QSWSDLHandler.The *methodreportNoWSDLinAxisServletisnevercalled.Perhaps themethodis *overwritteninsubclassesofAxisServletsothemethod wasn'tremoved. *Seethediscussionin * *http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23845 * *@param@param@param@paramres *@param@param@param@paramwriter *@param@param@param@parammoreDetailCode * optionalnameofamessagetoprovidemoredetail *@param@param@param@paramaxisFault * optionalfaultstring,forextrainfoatdebug timeonly */ protectedprotectedprotectedprotectedvoidvoidvoidvoidreportNoWSDL(HttpServletResponseres, PrintWriterwriter, StringmoreDetailCode,AxisFaultaxisFault){ } /** *Thismethodliststheavailableservices;itiscalledwhen Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第181页 共207 页 thereis *nothingtoexecuteonaGET * *@param@param@param@paramresponse *@param@param@param@paramwriter *@param@param@param@paramrequest *@throws@throws@throws@throwsConfigurationException *@throws@throws@throws@throwsAxisFault */ protectedprotectedprotectedprotectedvoidvoidvoidvoidreportAvailableServices(HttpServletResponse response, PrintWriterwriter,HttpServletRequestrequest) throwsthrowsthrowsthrowsConfigurationException,AxisFault{ AxisEngineengine=getEngine(); response.setContentType("text/html;charset=utf-8"); writer.println("

Andnow...SomeServices

"); Iteratori; trytrytrytry{ i=engine.getConfig().getDeployedServices(); } catchcatchcatchcatch(ConfigurationExceptionconfigException){ //turnanyinternalconfigurationexceptionsbackinto axisfaults //ifthatiswhattheyare ifififif(configException.getContainedException()instanceofinstanceofinstanceofinstanceof AxisFault){ throwthrowthrowthrow(AxisFault) configException.getContainedException(); } elseelseelseelse{ throwthrowthrowthrowconfigException; } } //baseURLmaychangeiftagisusedfor //customdeploymentatadifferentlocation StringdefaultBaseURL=getWebappBase(request)+ servicesPath; writer.println("
    "); whilewhilewhilewhile(i.hasNext()){ ServiceDescsd=(ServiceDesc)i.next(); StringBuffersb=newnewnewnewStringBuffer(); sb.append("
  • "); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第182页 共207 页 Stringname=sd.getName(); sb.append(name); sb.append("(wsdl)
  • "); writer.println(sb.toString()); ArrayListoperations=sd.getOperations(); ifififif(!operations.isEmpty()){ writer.println("
      "); forforforfor(Iteratorit=operations.iterator(); it.hasNext();){ OperationDescdesc=(OperationDesc)it.next(); writer.println("
    • "+desc.getName()); } writer.println("
    "); } } writer.println("
"); } /** *generatetheerrorresponsetoindicatethatthereis apparentlyno *endpointthere * *@param@param@param@paramrequest * therequestthatdidnthaveanedpoint *@param@param@param@paramresponse * responsewearegenerating *@param@param@param@paramwriter * openwriterfortherequest */ protectedprotectedprotectedprotectedvoidvoidvoidvoidreportCantGetAxisService(HttpServletRequest request, HttpServletResponseresponse,PrintWriterwriter){ //nosuchservice.... response.setStatus(HttpURLConnection.HTTP_NOT_FOUND); response.setContentType("text/html;charset=utf-8"); writer.println("

"+Messages.getMessage("error00")+ "

"); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第183页 共207 页 writer.println("

"+Messages.getMessage("noService06")+ "

"); } /** *probeforaJWSpageandreport'noservice'ifoneisnot foundthere * *@param@param@param@paramrequest * therequestthatdidnthaveanedpoint *@param@param@param@paramresponse * responsewearegenerating *@param@param@param@paramwriter * openwriterfortherequest */ protectedprotectedprotectedprotectedvoidvoidvoidvoidreportCantGetJWSService(HttpServletRequest request, HttpServletResponseresponse,PrintWriterwriter){ //firstlooktoseeifthereisaservice //requestPathisaworkaroundtosupportserving.jwsweb services //fromservicesURL-seeAXIS-843formoreinformation StringrequestPath=request.getServletPath() +((request.getPathInfo()!=nullnullnullnull)? request.getPathInfo():""); Stringrealpath= getServletConfig().getServletContext().getRealPath( requestPath); log.debug("JWSrealpath:"+realpath); booleanbooleanbooleanbooleanfoundJWSFile=(newnewnewnewFile(realpath).exists()) && (realpath.endsWith(Constants.JWS_DEFAULT_FILE_EXTENSION)); response.setContentType("text/html;charset=utf-8"); ifififif(foundJWSFile){ response.setStatus(HttpURLConnection.HTTP_OK); writer.println(Messages.getMessage("foundJWS00")+ "

"); Stringurl=request.getRequestURI(); Stringurltext=Messages.getMessage("foundJWS01"); writer.println(""+urltext +""); } elseelseelseelse{ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第184页 共207 页 response.setStatus(HttpURLConnection.HTTP_NOT_FOUND); writer.println(Messages.getMessage("noService06")); } } /** *ProcessaPOSTtotheservletbyhandingitofftotheAxis Engine.Here *iswhereSOAPmessagesarereceived * *@param@param@param@paramreq * postedrequest *@param@param@param@paramres * respose *@throws@throws@throws@throwsServletException * trouble *@throws@throws@throws@throwsIOException * differenttrouble */ publicpublicpublicpublicvoidvoidvoidvoiddoPost(HttpServletRequestreq,HttpServletResponse res) throwsthrowsthrowsthrowsServletException,IOException{ longlonglonglongt0=0,t1=0,t2=0,t3=0,t4=0; StringsoapAction=nullnullnullnull; MessageContextmsgContext=nullnullnullnull; ifififif(isDebug){ log.debug("Enter:doPost()"); } ifififif(tlog.isDebugEnabled()){ t0=System.currentTimeMillis(); } MessageresponseMsg=nullnullnullnull; StringcontentType=nullnullnullnull; trytrytrytry{ AxisEngineengine=getEngine(); ifififif(engine==nullnullnullnull){ //!!!shouldreturnaSOAPfault... ServletExceptionse=newnewnewnewServletException(Messages .getMessage("noEngine00")); log.debug("NoEngine!",se); throwthrowthrowthrowse; Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第185页 共207 页 } res.setBufferSize(1024 * 8); // provide performance boost. /** * get message context w/ various properties set */ msgContext = createMessageContext(engine, req, res); //?OK to move this to 'getMessageContext', //? where it would also be picked up for 'doGet()' ? ifififif (securityProvider != nullnullnullnull){ ifififif (isDebug){ log.debug("securityProvider:" + securityProvider); } msgContext.setProperty(MessageContext.SECURITY_PROVIDER, securityProvider); } /* * Get request message */ Message requestMsg = newnewnewnew Message(req.getInputStream(), falsefalsefalsefalse, req .getHeader(HTTPConstants.HEADER_CONTENT_TYPE), req .getHeader(HTTPConstants.HEADER_CONTENT_LOCATION)); // Transfer HTTP headers to MIME headers for request message. MimeHeaders requestMimeHeaders = requestMsg.getMimeHeaders(); forforforfor (Enumeration e = req.getHeaderNames(); e.hasMoreElements();) { String headerName = (String) e.nextElement(); forforforfor (Enumeration f = req.getHeaders(headerName); f .hasMoreElements();) { String headerValue = (String) f.nextElement(); requestMimeHeaders.addHeader(headerName, headerValue); } } Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第186页 共207 页 ifififif(isDebug){ log.debug("RequestMessage:"+requestMsg); /*Settherequest(incoming)messagefieldinthe context*/ /**********************************************************/ } msgContext.setRequestMessage(requestMsg); Stringurl=HttpUtils.getRequestURL(req).toString(); msgContext.setProperty(MessageContext.TRANS_URL,url); //putcharacterencodingofrequesttomessagecontext //inordertoreuseitduringthewholeprocess. StringrequestEncoding; trytrytrytry{ requestEncoding=(String)requestMsg .getProperty(SOAPMessage.CHARACTER_SET_ENCODING); ifififif(requestEncoding!=nullnullnullnull){ msgContext.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, requestEncoding); } } catchcatchcatchcatch(SOAPExceptione1){ } trytrytrytry{ /** *SavetheSOAPActionheaderintheMessageContext bag.This *willbeusedtotelltheAxisEnginewhich serviceisbeing *invoked.Thiswillsaveusthetroubleofhaving toparsethe *Requestmessage-althoughwewillneedto double-checklater *onthattheSOAPActionheaderdoesinfactmatch theURIin *thebody. */ //(isthislaststmttrue???(Idon'tthinkso- Glen)) Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第187页 共207 页 /********************************************************/ soapAction=getSoapAction(req); ifififif(soapAction!=nullnullnullnull){ msgContext.setUseSOAPAction(truetruetruetrue); msgContext.setSOAPActionURI(soapAction); } //CreateaSessionwrapperfortheHTTPsession. //Thesecan/shouldbepooledatsomepoint. //(SamisWatching!:-) msgContext.setSession(newnewnewnewAxisHttpSession(req)); ifififif(tlog.isDebugEnabled()){ t1=System.currentTimeMillis(); } /*InvoketheAxisengine...*/ /*****************************/ ifififif(isDebug){ log.debug("InvokingAxisEngine."); //herewerunthemessagebytheengine } engine.invoke(msgContext); ifififif(isDebug){ log.debug("ReturnfromAxisEngine."); } ifififif(tlog.isDebugEnabled()){ t2=System.currentTimeMillis(); } responseMsg=msgContext.getResponseMessage(); //Weusedtothrowexceptionsonnullresponse messages. //TheyareactuallyOKincertainsituations (asynchronous //services),sofallthroughhereandreturnan ACCEPTED //statuscodebelow.Mightwanttoinstalla configurable //errorcheckforthislater. } catchcatchcatchcatch(AxisFaultfault){ //logandsanitize Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第188页 共207 页 processAxisFault(fault); configureResponseFromAxisFault(res,fault); responseMsg=msgContext.getResponseMessage(); ifififif(responseMsg==nullnullnullnull){ responseMsg=newnewnewnewMessage(fault); ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()) .getMessage().setMessageContext(msgContext); } } catchcatchcatchcatch(Exceptione){ //otherexceptionsareinternaltrouble responseMsg=msgContext.getResponseMessage(); res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); responseMsg=convertExceptionToAxisFault(e, responseMsg); ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()) .getMessage().setMessageContext(msgContext); } catchcatchcatchcatch(Throwablet){ logException(t); //otherexceptionsareinternaltrouble responseMsg=msgContext.getResponseMessage(); res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); responseMsg=newnewnewnewMessage(newnewnewnewAxisFault(t.toString(), t)); ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()) .getMessage().setMessageContext(msgContext); } } catchcatchcatchcatch(AxisFaultfault){ processAxisFault(fault); configureResponseFromAxisFault(res,fault); responseMsg=msgContext.getResponseMessage(); ifififif(responseMsg==nullnullnullnull){ responseMsg=newnewnewnewMessage(fault); ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()) .getMessage().setMessageContext(msgContext); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第189页 共207 页 } } ifififif(tlog.isDebugEnabled()){ t3=System.currentTimeMillis(); } /*Sendresponsebackalongthewire...*/ /***********************************/ ifififif(responseMsg!=nullnullnullnull){ //TransferMIMEheaderstoHTTPheadersforresponse message. MimeHeadersresponseMimeHeaders= responseMsg.getMimeHeaders(); forforforfor(Iteratori=responseMimeHeaders.getAllHeaders(); i.hasNext();){ MimeHeaderresponseMimeHeader=(MimeHeader) i.next(); res.addHeader(responseMimeHeader.getName(), responseMimeHeader .getValue()); } //synchronizethecharacterencodingofrequestand response StringresponseEncoding=(String)msgContext .getProperty(SOAPMessage.CHARACTER_SET_ENCODING); ifififif(responseEncoding!=nullnullnullnull){ trytrytrytry{ responseMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, responseEncoding); } catchcatchcatchcatch(SOAPExceptione){ } } //determinecontenttypefrommessageresponse contentType=responseMsg.getContentType(msgContext .getSOAPConstants()); sendResponse(contentType,res,responseMsg); } elseelseelseelse{ //Nocontent,sojustindicateaccepted res.setStatus(202); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第190页 共207 页 } ifififif(isDebug){ log.debug("Responsesent."); log.debug("Exit:doPost()"); } ifififif(tlog.isDebugEnabled()){ t4=System.currentTimeMillis(); tlog.debug("axisServlet.doPost:" +soapAction +"pre=" +(t1-t0) +"invoke=" +(t2-t1) +"post=" +(t3-t2) +"send=" +(t4-t3) +"" +msgContext.getTargetService() +"." +((msgContext.getOperation()==nullnullnullnull)?"": msgContext .getOperation().getName())); } } /** *Configuretheservletresponsestatuscodeandmaybeother headersfrom *thefaultinfo. * *@param@param@param@paramresponse * responsetoconfigure *@param@param@param@paramfault * whatwentwrong */ privateprivateprivateprivatevoidvoidvoidvoid configureResponseFromAxisFault(HttpServletResponseresponse, AxisFaultfault){ //thengetthestatuscode //It'sbeensuggestedthatalackofSOAPAction //shouldproducesomeothererrorcode(inthe400s)... Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第191页 共207 页 intintintintstatus=getHttpServletResponseStatus(fault); ifififif(status==HttpServletResponse.SC_UNAUTHORIZED){ //unauthaccessresultsinauthenticationrequest //TODOTODOTODOTODO:lessgenericrealmchoice? response.setHeader("WWW-Authenticate","Basic realm=\"AXIS\""); } response.setStatus(status); } /** *turnanyExceptionintoanAxisFault,logit,setthe responsestatus *codeaccordingtowhatthespecificationssayandreturna response *messageforposting.Thiswillbetheresponsemessage passedinif *non-null;onegeneratedfromthefaultotherwise. * *@param@param@param@paramexception * whatwentwrong *@param@param@param@paramresponseMsg * whatresponsewehave(ifany) *@return@return@return@returnaresponsemessagetosendtotheuser */ privateprivateprivateprivateMessageconvertExceptionToAxisFault(Exception exception, MessageresponseMsg){ logException(exception); ifififif(responseMsg==nullnullnullnull){ AxisFaultfault=AxisFault.makeFault(exception); processAxisFault(fault); responseMsg=newnewnewnewMessage(fault); } returnreturnreturnreturnresponseMsg; } /** *ExtractinformationfromAxisFaultandmapittoaHTTP Statuscode. * *@param@param@param@paramaf * AxisFault *@return@return@return@returnHTTPStatuscode. Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第192页 共207 页 */ protectedprotectedprotectedprotectedintintintintgetHttpServletResponseStatus(AxisFaultaf){ //TODOTODOTODOTODO:Shouldreallybedoingthiswithexplicit AxisFault //subclasses...--Glen returnreturnreturnreturn af.getFaultCode().getLocalPart().startsWith("Server.Unauth")? HttpServletResponse.SC_UNAUTHORIZED :HttpServletResponse.SC_INTERNAL_SERVER_ERROR; //Thiswillraisea401forboth //"Unauthenticated"&"Unauthorized"... } /** *writeamessagetotheresponse,setappropriateheaders forcontent *type..etc. * *@param@param@param@paramres * response *@param@param@param@paramresponseMsg * messagetowrite *@throws@throws@throws@throwsAxisFault *@throws@throws@throws@throwsIOException * iftheresponsestreamcannotbewrittento */ privateprivateprivateprivatevoidvoidvoidvoidsendResponse(StringcontentType, HttpServletResponseres, MessageresponseMsg)throwsthrowsthrowsthrowsAxisFault,IOException{ ifififif(responseMsg==nullnullnullnull){ res.setStatus(HttpServletResponse.SC_NO_CONTENT); ifififif(isDebug){ log.debug("NOAXISMESSAGETORETURN!"); //Stringresp=Messages.getMessage("noData00"); //res.setContentLength((int) resp.getBytes().length); //res.getWriter().print(resp); } } elseelseelseelse{ ifififif(isDebug){ log.debug("ReturnedContent-Type:"+contentType); //log.debug("ReturnedContent-Length:"+ //responseMsg.getContentLength()); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第193页 共207 页 } trytrytrytry{ res.setContentType(contentType); /* *MyunderstandofContent-LengthHTTP1.0- Requiredfor *requests,butoptionalforresponses.HTTP1.1- Either *Content-LengthorHTTPChunkingisrequired.Most servlet *engineswilldochunkingifcontent-lengthisnot specified. */ //if(clientVersion== HTTPConstants.HEADER_PROTOCOL_V10)//do //chunkingifnecessary. // res.setContentLength(responseMsg.getContentLength()); responseMsg.writeTo(res.getOutputStream()); } catchcatchcatchcatch(SOAPExceptione){ logException(e); } } ifififif(!res.isCommitted()){ res.flushBuffer();//Forceitrightnow. } } /** *PlacetheRequestmessageintheMessagContextobject- noticethatwe *justleaveitasa'ServletRequest'objectandletthe Messageprocessing *routineconvertit-wedon'tdoitsincewedon'tknowhow it'sgoingto *beused-perhapsitmightnotevenneedtobeparsed. * *@return@return@return@returnamessagecontext */ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第194页 共207 页 privateprivateprivateprivateMessageContextcreateMessageContext(AxisEngineengine, HttpServletRequestreq,HttpServletResponseres){ MessageContextmsgContext=newnewnewnewMessageContext(engine); StringrequestPath=getRequestPath(req); ifififif(isDebug){ log.debug("MessageContext:"+msgContext); log.debug("HEADER_CONTENT_TYPE:" + req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE)); log.debug("HEADER_CONTENT_LOCATION:" + req.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION)); log.debug("Constants.MC_HOME_DIR:"+ String.valueOf(getHomeDir())); log.debug("Constants.MC_RELATIVE_PATH:"+requestPath); log.debug("HTTPConstants.MC_HTTP_SERVLETLOCATION:" +String.valueOf(getWebInfPath())); log.debug("HTTPConstants.MC_HTTP_SERVLETPATHINFO:" +req.getPathInfo()); log.debug("HTTPConstants.HEADER_AUTHORIZATION:" + req.getHeader(HTTPConstants.HEADER_AUTHORIZATION)); log.debug("Constants.MC_REMOTE_ADDR:"+ req.getRemoteAddr()); log.debug("configPath:"+ String.valueOf(getWebInfPath())); } /*SettheTransport*/ /*********************/ msgContext.setTransportName(transportName); /*SavesomeHTTPspecificinfointhebagincasesomeone needsit*/ /************************************************************* *******/ msgContext.setProperty(Constants.MC_JWS_CLASSDIR, jwsClassDir); msgContext.setProperty(Constants.MC_HOME_DIR,getHomeDir()); msgContext.setProperty(Constants.MC_RELATIVE_PATH, requestPath); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第195页 共207 页 msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLET,thisthisthisthis); msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST, req); msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE, res); msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION, getWebInfPath()); msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO, req .getPathInfo()); msgContext.setProperty(HTTPConstants.HEADER_AUTHORIZATION, req .getHeader(HTTPConstants.HEADER_AUTHORIZATION)); msgContext.setProperty(Constants.MC_REMOTE_ADDR, req.getRemoteAddr()); //Setupajavax.xml.rpc.server.ServletEndpointContext ServletEndpointContextImplsec=newnewnewnew ServletEndpointContextImpl(); msgContext.setProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT, sec); /*Savetherealpath*/ /**********************/ Stringrealpath= getServletConfig().getServletContext().getRealPath( requestPath); ifififif(realpath!=nullnullnullnull){ msgContext.setProperty(Constants.MC_REALPATH,realpath); } msgContext.setProperty(Constants.MC_CONFIGPATH, getWebInfPath()); returnreturnreturnreturnmsgContext; } /** *ExtracttheSOAPActionheader.ifSOAPActionisnullthen Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第196页 共207 页 we'llwebe *forcedtoscanthebodyforit.ifSOAPActionis""then usetheURL * *@param@param@param@paramreq * incomingrequest *@return@return@return@returntheaction *@throws@throws@throws@throwsAxisFault */ privateprivateprivateprivateStringgetSoapAction(HttpServletRequestreq)throwsthrowsthrowsthrows AxisFault{ StringsoapAction= req.getHeader(HTTPConstants.HEADER_SOAP_ACTION); ifififif(soapAction==nullnullnullnull){ StringcontentType=req .getHeader(HTTPConstants.HEADER_CONTENT_TYPE); ifififif(contentType!=nullnullnullnull){ intintintintindex=contentType.indexOf("action"); ifififif(index!=-1){ soapAction=contentType.substring(index+7); } } } ifififif(isDebug){ log.debug("HEADER_SOAP_ACTION:"+soapAction); /** *Technically,ifwedon'tfindthisheader,weshould probably *fault.It'srequiredintheSOAPHTTPbinding. */ } //if(soapAction==null){ //AxisFaultaf=newAxisFault("Client.NoSOAPAction", Messages //.getMessage("noHeader00","SOAPAction"),null,null); // //exceptionLog.error(Messages.getMessage("genFault00"), af); // //throwaf; //} //theSOAP1.1spec&WS-I1.0says: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第197页 共207 页 //soapaction="SOAPAction"":"[<">URI-reference<">] //someimplementationsleaveoffthequotes //westripthemiftheyarepresent //if(soapAction.startsWith("\"")&& soapAction.endsWith("\"") //&&soapAction.length()>=2){ //intend=soapAction.length()-1; //soapAction=soapAction.substring(1,end); //} //if(soapAction.length()==0){ //soapAction=req.getContextPath();//Isthisright? // //} returnreturnreturnreturnreq.getContextPath(); } /** *ProvidedtoallowoverloadofdefaultJWSClassDirby derivedclass. * *@return@return@return@returndirectoryforJWSfiles */ protectedprotectedprotectedprotectedStringgetDefaultJWSClassDir(){ returnreturnreturnreturn(getWebInfPath()==nullnullnullnull)?nullnullnullnull//???whatisa goodFINAL //defaultforWebLogic? :getWebInfPath()+File.separator+"jwsClasses"; } /** *InitializeaHandlerforthetransportdefinedintheAxis serverconfig. *Thisincludesoptionallyfillinginquerystringhandlers. */ publicpublicpublicpublicvoidvoidvoidvoidinitQueryStringHandlers(){ trytrytrytry{ thisthisthisthis.transport= getEngine().getTransport(thisthisthisthis.transportName); ifififif(thisthisthisthis.transport==nullnullnullnull){ //Notransportbythisnameisdefined.Therefore, fillin Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第198页 共207 页 //default //querystringhandlers. thisthisthisthis.transport=newnewnewnewSimpleTargetedChain(); thisthisthisthis.transport.setOption("qs.list", "org.apache.axis.transport.http.QSListHandler"); thisthisthisthis.transport.setOption("qs.method", "org.apache.axis.transport.http.QSMethodHandler"); thisthisthisthis.transport.setOption("qs.wsdl", "org.apache.axis.transport.http.QSWSDLHandler"); returnreturnreturnreturn; } elseelseelseelse{ //Seeifweshouldusethedefaultquerystring handlers. //Bydefault,setthistotrue(forbackwards compatibility). booleanbooleanbooleanbooleandefaultQueryStrings=truetruetruetrue; StringuseDefaults=(String)thisthisthisthis.transport .getOption("useDefaultQueryStrings"); ifififif((useDefaults!=nullnullnullnull) &&useDefaults.toLowerCase().equals("false")) { defaultQueryStrings=falsefalsefalsefalse; } ifififif(defaultQueryStrings==truetruetruetrue){ //Weshouldusedefaults,sofillthemin. thisthisthisthis.transport.setOption("qs.list", "org.apache.axis.transport.http.QSListHandler"); thisthisthisthis.transport.setOption("qs.method", "org.apache.axis.transport.http.QSMethodHandler"); thisthisthisthis.transport.setOption("qs.wsdl", Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第199页 共207 页 "org.apache.axis.transport.http.QSWSDLHandler"); } } } catchcatchcatchcatch(AxisFaulte){ //Somesortofproblemoccurred,let'sjustmakea default //transport. thisthisthisthis.transport=newnewnewnewSimpleTargetedChain(); thisthisthisthis.transport.setOption("qs.list", "org.apache.axis.transport.http.QSListHandler"); thisthisthisthis.transport.setOption("qs.method", "org.apache.axis.transport.http.QSMethodHandler"); thisthisthisthis.transport.setOption("qs.wsdl", "org.apache.axis.transport.http.QSWSDLHandler"); returnreturnreturnreturn; } } /** *Attemptstoinvokeapluginforthequerystringsupplied intheURL. * *@param@param@param@paramrequest * theservlet'sHttpServletRequestobject. *@param@param@param@paramresponse * theservlet'sHttpServletResponseobject. *@param@param@param@paramwriter * theservlet'sPrintWriterobject. */ privateprivateprivateprivatebooleanbooleanbooleanbooleanprocessQuery(HttpServletRequestrequest, HttpServletResponseresponse,PrintWriterwriter) throwsthrowsthrowsthrowsAxisFault{ //Attempttoinstantiateaplug-inhandlerclassforthe querystring //handlerclassesdefinedintheHTTPtransport. Stringpath=request.getServletPath(); StringqueryString=request.getQueryString(); Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第200页 共207 页 StringserviceName; AxisEngineengine=getEngine(); Iteratori= thisthisthisthis.transport.getOptions().keySet().iterator(); ifififif(queryString==nullnullnullnull){ returnreturnreturnreturnfalsefalsefalsefalse; } StringservletURI=request.getContextPath()+path; StringreqURI=request.getRequestURI(); //chopoff'/'. ifififif(servletURI.length()+1 AxisServlet Apache-AxisServlet Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第204页 共207 页 org.apache.axis.transport.http.AxisServlet 写上你自己的类就可以了。 然后开始我们的 server 编写,这里为了让大家更好的理解 如图: 上面的图是做业务的 有持久层 数据模型 和业务层 这个主要是做用户查询的,然后在看如 图: 这2个是服务端要封装的模型,UserInfo 装了 2个属性一个是用户名一个是用户密码 UserResq 是封装了 返回给客户端的一个模型。这个做的好处就是面向对象 现在开始写我们的 WS提供的接口: 这里的 UserManagerServer 就是 WS提供的对外访问接口,现在我们用 ant 来进行 wsdl 的生成 来看下代码: /* *文件名: UserManagerServer.java * *创建日期: 2009-4-1 * *Copyright(C)2009,byxiaozhi. * *原始作者:xiaozhi * */ Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第205页 共207 页 packagepackagepackagepackagewebservice.ash.server; importimportimportimportjava.rmi.Remote; importimportimportimportjava.rmi.RemoteException; importimportimportimportwebservice.test.module.UserResq; /** *WS提供的接口 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2009-4-1 */ publicpublicpublicpublicinterfaceinterfaceinterfaceinterfaceUserManagerServerextendsextendsextendsextendsRemote{ publicpublicpublicpublicUserResqgetAllUsers()throwsthrowsthrowsthrowsRemoteException; } 现在通过 ANT 生成 WSDL ant 如下: 解释一下这个意思: Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第206页 共207 页 Classname: 接口名字 Bindingname:接口的实现类 HttpBinding是后缀 Porttypename:接口类型名 PortType后缀 Namespace:命名空间 剩下的就不用了。 然后我们就会生成一个 WSDL文件,但是这个 WSDL需要改动一下,为什么呢?首先是我们获取 所有用户但是 Hibernate查询出来是一个 list在soap和java类型对应中就没有所以我们 要转换成数组,但是如果在 UserResq里写上数组 那生成 WSDL就不会识别出来。所以在没生 成WSDL你可以不写成数组然后 在生成 WSDL你在修改 最后通过 WSDL生成自己的 JAVA服务 端类就可以了。来看一段 WSDL的代码: 如果你你的 UserResq对象里装有的 UserInfo是一个数组就要写上红色字的哪句话,这个表 示UserInfo在UserResq可以出现多次。 最后通过 WSDL生成 JAVA类,执行命令:javaorg.apache.axis.wsdl.WSDL2Java-- server-side文件路径名 这样就会生成了相应的代码看图: 以上的图就是给你生成的代码,然后UserManagerServerHttpBindingImpl就是你的服务 端实现,你直接在方法里添加业务就行了。 现在我们用测试来测试我们的服务端,来看代码: /* *文件名: TestClient.java * *创建日期: 2009-4-1 * *Copyright(C)2009,byxiaozhi. * Web Service 开发指南 官方网址:http://www.hlmz.org QQ群:3961326 第207页 共207 页 *原始作者:xiaozhi * */ packagepackagepackagepackagewebservice.ash.client; importimportimportimportjava.net.MalformedURLException; importimportimportimportjava.net.URL; importimportimportimportjava.rmi.RemoteException; importimportimportimportjavax.xml.rpc.ServiceException; importimportimportimportwebservice.ash.server.UserManagerServerPortType; importimportimportimportwebservice.ash.server.UserManagerServerPortTypeService; importimportimportimport webservice.ash.server.UserManagerServerPortTypeServiceLocator; importimportimportimportwebservice.ash.server.module.UserInfo; importimportimportimportwebservice.ash.server.module.UserResq; /** *客户端测试服务端用户是否执行 * *@author@author@author@authorxiaozhi * *@version@version@version@version$Revision$ * *@since@since@since@since2009-4-1 */ publicpublicpublicpublicclassclassclassclassTestClient{ publicpublicpublicpublicstaticstaticstaticstaticvoidvoidvoidvoidmain(String[]args){ UserManagerServerPortTypeServiceservices=newnewnewnew UserManagerServerPortTypeServiceLocator(); trytrytrytry{ URLurl=newnewnewnew URL("http://127.0.0.1:8080/myaxis/services/UserManagerServer"); UserManagerServerPortTypeclient= services.getUserManagerServer(url); UserResquserResq=client.getAllUsers(); UserInfo[]users=userResq.getUserInfo(); forforforfor(intintintinti=0;i

还剩207页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 20 金币 [ 分享pdf获得金币 ] 58 人已下载

下载pdf

pdf贡献者

522179535

贡献于2010-12-07

下载需要 20 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf