已阅读5页,还剩39页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
用Axis2实现Web Service,虽然可以将POJO类放在axis2WEB-INFpojo目录中直接发布成Web Service,这样做不需要进行任何配置,但这些POJO类不能在任何包中。这似乎有些不方便,为此,Axis2也允许将带包的POJO类发布成Web Service。 先实现一个POJO类,代码如下:packageservice;publicclassMyServicepublicStringgetGreeting(Stringname)return您好+name;publicvoidupdate(Stringdata)System.out.println(已经更新);这个类有两个方法,这两个方法都需要发布成Web Service方法。这种方式和直接放在pojo目录中的POJO类不同。要想将MyService类发布成Web Service,需要一个services.xml文件,这个文件需要放在META-INF目录中,该文件的内容如下:WebService例子service.MyService其中元素用于发布Web Service,一个元素只能发布一个WebService类,name属性表示WebService名,如下面的URL可以获得这个WebService的WSDL内容:http:/localhost:8080/axis2/services/myService?wsdl 其中name属性名就是上面URL中?和/之间的部分。元素表示当前Web Service的描述,元素用于设置WebService的参数,在这里用于设置WebService对应的类名。在这里最值得注意的是元素,该元素用于设置处理WebService方法的处理器。例如,getGreeting方法有一个返回值,因此,需要使用可处理输入输出的RPCMessageReceiver类,而update方法没有返回值,因此,需要使用只能处理输入的RPCInOnlyMessageReceiver类。使用这种方式发布WebService,必须打包成.aar文件,.aar文件实际上就是改变了扩展名的.jar文件。在现在建立了两个文件:MyService.java和services.xml。将MyService.java编译,生成MyService.class。services.xml和MyService.class文件的位置如下:D:wsserviceMyService.classD:wsMETA-INFservices.xml 在windows控制台中进入ws目录,并输入如下的命令生成.aar文件(实际上,.jar文件也可以发布webservice,但axis2官方文档中建议使用.aar文件发布webservice):jar cvf ws.aar . 最后将ws.aar文件复制到webappsaxis2WEB-INFservices目录中,启动Tomcat后,就可以调用这个WebService了。调用的方法和WebService大讲堂之Axis2(1):用POJO实现0配置的WebService所讲的方法类似。另外services.xml文件中也可以直接指定WebService类的方法,如可以用下面的配置代码来发布WebService:WebService例子service.MyService上面的配置代码前面的部分和以前的services.xml文件的内容相同,但后面使用了元素来指定每一个WebService方法,并单独指定了处理每一个方法的处理器。对于客户端来说,调用使用这两个services.xml文件发布的WebService并没有太大我区别,只是使用第二个services.xml文件发布WebServices后,在使用wsdl2java命令或使用C#、delphi等生成客户端的stub时,update方法的String类型被封装在了update类中,在传递update方法的参数时需要建立update类的对象实例。而使用第一个services.xml文件发布的WebService在生成stub时直接可以为update方法传递String类型的参数。从这一点可以看出,这两种方法生成的WSDL有一定的区别。但实际上,如果客户端程序使用第一个services.xml文件发布的WebService生成stub类时(这时update方法的参数是String),在服务端又改为第二个services.xml文件来发布WebService,这时客户端并不需要再重新生成stub类,而可以直接调用update方法。也就是说,服务端使用什么样的方式发布WebService,对客户端并没有影响。如果想发布多个WebService,可以使用元素,如再建立一个MyService1类,代码如下:packageservicepublicclassMyService1publicStringgetName()returnbill;在services.xml文件中可以使用如下的配置代码来配置MyService和MyService1类: WebService例子 service.MyService WebService例子 service.MyService1 在WebService大讲堂之Axis2(2):复合类型数据的传递中讲过,如果要传递二进制文件(如图像、音频文件等),可以使用byte作为数据类型进行传递,然后客户端使用RPC方式进行调用。这样做只是其中的一种方法,除此之外,在客户端还可以使用wsdl2java命令生成相应的stub类来调用WebService,wsdl2java命令的用法详见WebService大讲堂之Axis2(1):用POJO实现0配置的WebService。 WebService类中包含byte类型参数的方法在wsdl2java生成的stub类中对应的数据类型不再是byte类型,而是javax.activation.DataHandler。DataHandler类是专门用来映射WebService二进制类型的。 在WebService类中除了可以使用byte作为传输二进制的数据类型外,也可以使用javax.activation.DataHandler作为数据类型。 不管是使用byte,还是使用javax.activation.DataHandler作为WebService方法的数据类型,使用wsdl2java命令生成的stub类中相应方法的类型都是javax.activation.DataHandler。而象使用.net、delphi生成的stub类的相应方法类型都是byte。这是由于javax.activation.DataHandler类是Java特有的,对于其他语言和技术来说,并不认识javax.activation.DataHandler类,因此,也只有使用最原始的byte了。 下面是一个上传二进制文件的例子,WebService类的代码如下:packageservice;importjava.io.InputStream;importjava.io.OutputStream;importjava.io.FileOutputStream;importjavax.activation.DataHandler;publicclassFileService/使用byte类型参数上传二进制文件publicbooleanuploadWithByte(bytefile,Stringfilename)FileOutputStreamfos=null;tryfos=newFileOutputStream(filename);fos.write(file);fos.close();catch(Exceptione)returnfalse;finallyif(fos!=null)tryfos.close();catch(Exceptione)returntrue;privatevoidwriteInputStreamToFile(InputStreamis,OutputStreamos)throwsExceptionintn=0;bytebuffer=newbyte8192;while(n=is.read(buffer)0)os.write(buffer,0,n);/使用DataHandler类型参数上传文件publicbooleanuploadWithDataHandler(DataHandlerfile,Stringfilename)FileOutputStreamfos=null;tryfos=newFileOutputStream(filename);/可通过DataHandler类的getInputStream方法读取上传数据writeInputStreamToFile(file.getInputStream(),fos);fos.close();catch(Exceptione)returnfalse;finallyif(fos!=null)tryfos.close();catch(Exceptione)returntrue;上面代码在services.xml文件的配置代码如下:文件服务service.FileService 如果使用wsdl2java命令生成调用Java客户端代码,则需要创建DataHandler类的对象实例,代码如下:DataHandlerdh=newDataHandler(newFileDataSource(imagePath);wsdl2java命令会为每一个方法生成一个封装方法参数的类,类名为方法名(第一个字符大写),如uploadWithByte方法生成的类名为UploadWithByte。如果要设置file参数的值,可以使用UploadWithByte类的setFile方法,代码如下:UploadWithByteuwb=newUPloadWithByte();uwb.setFile(dh);最后是调用uploadWithByte方法,代码如下(FileServiceStub为wsdl2java生成的stub类名):FileServiceStubfss=newFileServiceStub();fss.uploadWithByte(uwb);如果使用C#调用FileService,则file参数类型均为byte,代码如下:MemoryStreamms=newMemoryStream();Bitmapbitmap=newBitmap(picUpdateImage.Image);bitmap.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);service.fileServicefs=newWSC.service.fileService();fs.uploadWithDataHandler(ms.ToArray();fs.uploadWithByte(ms.ToArray();其中picUpdateImage为c#中加载图像文件的picturebox控件。WebService给人最直观的感觉就是由一个个方法组成,并在客户端通过SOAP协议调用这些方法。这些方法可能有返回值,也可能没有返回值。虽然这样可以完成一些工具,但这些被调用的方法是孤立的,当一个方法被调用后,在其他的方法中无法获得这个方法调用后的状态,也就是说无法保留状态。读者可以想象,这对于一个完整的应用程序,无法保留状态,就意味着只依靠WebService很难完成全部的工作。例如,一个完整的应用系统都需要进行登录,这在Web应用中使用Session来保存用户登录状态,而如果用WebService的方法来进行登录处理,无法保存登录状态是非常令人尴尬的。当然,这也可以通过其他的方法来解决,如在服务端使用static变量来保存用户状态,并发送一个id到客户端,通过在服务端和客户端传递这个id来取得相应的用户状态。这非常类似于Web应用中通过Session和Cookie来管理用户状态。但这就需要由开发人员做很多工作,不过幸好Axis2为我们提供了WebService状态管理的功能。使用Axis2来管理WebService的状态基本上对于开发人员是透明的。在WebService类需要使用org.apache.axis2.context.MessageContext和org.apache.axis2.context.ServiceContext类来保存与获得保存在服务端的状态信息,这有些象使用HttpSession接口的getAttribute和setAttribute方法获得与设置Session域属性。除此之外,还需要修改services.xml文件的内容,为元素加一个scope属性,该属性有四个可取的值:Application, SOAPSession, TransportSession, Request,不过要注意一下,虽然Axis2的官方文档将这四个值的单词首字母和缩写字母都写成了大写,但经笔者测试,必须全部小写才有效,也就是这四个值应为:application、soapsession、transportsession、request,其中request为scope属性的默认值。读者可以选择使用transportsession和application分别实现同一个WebService类和跨WebService类的会话管理。在客户端需要使用setManageSession(true)打开Session管理功能。综上所述,实现同一个WebService的Session管理需要如下三步:1.使用MessageContext和ServiceContext获得与设置key-value对。2.为要进行Session管理的WebService类所对应的元素添加一个scope属性,并将该属性值设为transportsession。3.在客户端使用setManageSession(true)打开Session管理功能。下面是一个在同一个WebService类中管理Session的例子。先建立一个WebService类,代码如下:packageservice;importorg.apache.axis2.context.ServiceContext;importorg.apache.axis2.context.MessageContext;publicclassLoginServicepublicbooleanlogin(Stringusername,Stringpassword)if(bill.equals(username)&1234.equals(password)/第1步:设置key-value对MessageContextmc=MessageContext.getCurrentMessageContext();ServiceContextsc=mc.getServiceContext();sc.setProperty(login,成功登录);returntrue;elsereturnfalse;publicStringgetLoginMsg()/第1步:获得key-value对中的valueMessageContextmc=MessageContext.getCurrentMessageContext();ServiceContextsc=mc.getServiceContext();return(String)sc.getProperty(login);在LoginService类中有两个方法:login和getLoginMsg,如果login方法登录成功,会将“成功登录”字符串保存在ServiceContext对象中。如果在login方法返回true后调用getLoginMsg方法,就会返回“成功登录”。下面是LoginService类的配置代码(services.xml):登录服务service.LoginService使用如下的命令生成客户端使用的stub类:%AXIS2_HOME%binwsdl2java-urihttp:/localhost:8080/axis2/services/loginService?wsdl-pclient-s-ostub在stubsrcclient目录中生成了一个LoginServiceStub.java类,在该类中找到如下的构造句方法:publicLoginServiceStub(org.apache.axis2.context.ConfigurationContextconfigurationContext,java.lang.StringtargetEndpoint,booleanuseSeparateListener)throwsorg.apache.axis2.AxisFault _serviceClient.getOptions().setSoapVersionURI( org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);在该方法中最后添加如下的代码:/第3步:打开客户端的Session管理功能_serviceClient.getOptions().setManageSession(true);下面的客户端代码使用LoginServiceStub对象访问了刚才建立的WebService:LoginServiceStubstub=newLoginServiceStub();LoginServiceStub.Loginlogin=newLoginServiceStub.Login();login.setUsername(bill);login.setPassword(1234);if(stub.login(login).local_return)System.out.println(stub.getLoginMsg().local_return);运行上面的代码后,会输出“成功登录”信息。在WebService大讲堂之Axis2(5):会话(Session)管理一文中介绍了如何使用Axis2来管理同一个服务的会话,但对于一个复杂的系统,不可能只有一个WebService服务,例如,至少会有一个管理用户的WebService(用户登录和注册)以及处理业务的WebService。象这种情况,就必须在多个WebService服务之间共享会话状态,也称为跨服务会话(Session)管理。实现跨服务会话管理与实现同一个服务的会话管理的步骤类似,但仍然有一些差别,实现跨服务会话管理的步骤如下:实现跨服务的Session管理需要如下三步:1.使用MessageContext和ServiceGroupContext获得与设置key-value对。2.为要进行Session管理的WebService类所对应的元素添加一个scope属性,并将该属性值设为application。3.在客户端使用setManageSession(true)打开Session管理功能。从上面的步骤可以看出,实现跨服务会话管理与实现同一个服务的会话管理在前两步上存在着差异,而第3步是完全一样的。下面是一个跨服务的会话管理的实例。在这个例子中有两个WebService类:LoginService和SearchService,代码如下:LoginService.javapackageservice;importorg.apache.axis2.context.MessageContext;importorg.apache.axis2.context.ServiceGroupContext;publicclassLoginServicepublicbooleanlogin(Stringusername,Stringpassword)if(bill.equals(username)&1234.equals(password)/第1步:设置key-value对MessageContextmc=MessageContext.getCurrentMessageContext();ServiceGroupContextsgc=mc.getServiceGroupContext();sgc.setProperty(login,成功登录);returntrue;elsereturnfalse;publicStringgetLoginMsg()/第1步:获得key-value对中的valueMessageContextmc=MessageContext.getCurrentMessageContext();ServiceGroupContextsgc=mc.getServiceGroupContext();return(String)sgc.getProperty(login);SearchService.javapackageservice;importorg.apache.axis2.context.MessageContext;importorg.apache.axis2.context.ServiceGroupContext;publicclassSearchServicepublicStringfindByName(Stringname)/第1步:获得key-value对中的valueMessageContextmc=MessageContext.getCurrentMessageContext();ServiceGroupContextsgc=mc.getServiceGroupContext();if(sgc.getProperty(login)!=null)return找到的数据;elsereturn用户未登录;services.xml文件中的配置代码如下:登录服务service.LoginService搜索服务service.SearchService第3步与WebService大讲堂之Axis2(5):会话(Session)管理一文中介绍的方法类似。下面是使用两个stub类的对象实例访问上面实现的两个WebService的客户端代码:LoginServiceStubstub=newLoginServiceStub();LoginServiceStub.Loginlogin=newLoginServiceStub.Login();login.setUsername(bill);login.setPassword(1234);if(stub.login(login).local_return)System.out.println(stub.getLoginMsg().local_return);SearchServiceStubsearchStub=newSearchServiceStub();SearchServiceStub.FindByNamefbn=newSearchServiceStub.FindByName();fbn.setName(abc);System.out.println(searchStub.findByName(fbn).local_return);在执行上面的代码后,将输出如下的信息:成功登录找到的数据读者可以将scope属性值改成transportsession,看看会输出什么! 实际上,Axis2的会话管理也是通过Cookie实现的,与Web应用中的Session管理类似。如果读者使用C#访问支持会话(在同一个服务中的会话管理)的WebService,需要指定一个CookieContainer对象,代码如下:service.loginServicels=newservice.loginService();System.Net.CookieContainercc=newSystem.Net.CookieContainer();ls.CookieContainer=cc;boolr,rs;ls.login(bill,1234,outr,outrs);if(r)MessageBox.Show(ls.getLoginMsg().return);如果是访问跨服务的支持会话的WebService,则不需要指定CookieContainer对象,代码如下:service.loginServicels=newservice.loginService();boolr,rs;ls.login(bill,1234,outr,outrs);if(r)service1.searchServicess=newservice1.searchService();MessageBox.Show(ss.findByName(abc);如果读者使用delphi(本文使用的是delphi2009,其他的delphi版本请读者自行测试)调用支持会话的WebService时有一些差别。经笔者测试,使用delphi调用WebService,将scope属性值设为transportsession和application都可以实现跨服务的会话管理,这一点和Java与C#不同,Java和C#必须将scope属性值设为application才支持跨服务会话管理。在delphi中不需要象C#指定一个CookieContainer或其他类似的对象,而只需要象访问普通的WebService一样访问支持会话的WebService即可。在现今的Web应用中经常使用Spring框架来装载JavaBean。如果要想将某些在Spring中装配的JavaBean发布成WebService,使用Axis2的Spring感知功
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 初中地生会考试卷及答案
- 叉车考试实操试题及答案
- 护士卫生招聘试题及答案
- 2025-2026人教版五年级期末语文测试
- 2025-2026七年级地理上学期测试湘教版卷
- 《东北草甸草原家畜混合放牧技术规程》征求意见稿
- 卫生室药房管理制度
- 回转窑卫生管理制度
- 品牌卫生巾代理制度
- 外包工职业卫生管理制度
- 2025年中国萝卜干市场调查研究报告
- 国家中医药管理局《中医药事业发展“十五五”规划》全文
- 师德师风个人总结课件
- 化学-江苏省苏州市2024-2025学年第一学期学业质量阳光指标调研卷暨高二上学期期末考试试题和答案
- 精神科疑难病例讨论
- 腾讯00后研究报告
- 固体废物 铅和镉的测定 石墨炉原子吸收分光光度法(HJ 787-2016)
- DB45-T 2675-2023 木薯米粉加工技术规程
- 板材眼镜生产工艺
- Unit 3 My weekend plan B Let's talk(教案)人教PEP版英语六年级上册
- 实习考勤表(完整版)
评论
0/150
提交评论