axis2实现WebService之复合类型数据的传递_第1页
axis2实现WebService之复合类型数据的传递_第2页
axis2实现WebService之复合类型数据的传递_第3页
axis2实现WebService之复合类型数据的传递_第4页
axis2实现WebService之复合类型数据的传递_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

axis2实现WebService之复合类型数据的传递接着昨天的程序,今天又进了一步,学习了webservice的复合类型数据的传递,尤其是教程上没有的部分,我自己尝试着写,虽说耗费了一个下午的时间,但是还是非常值的,废话少说,看招!在实际的应用中,不仅需要使用WebService来传递简单类型的数据,有时也需要传递更复杂的数据,这些数据可以被称为复合类型的数据。数组与类(接口)是比较常用的复合类型。在Axis2中可以直接使用将WebService方法的参数或返回值类型声明成数组或类(接口)。但要注意,在定义数组类型时只能使用一维数组,如果想传递多维数组,可以使用分隔符进行分隔,如下面的代码所示:String[]strArray=newString[]{"自行车,飞机,火箭","中国,美国,德国","超人,蜘蛛侠,钢铁侠"};上面的代码可以看作是一个3*3的二维数组。在传递类的对象实例时,除了直接将数组类型声明成相应的类或接口,也可以将对象实例进行序列化,也就是说,将一个对象实例转换成字节数组进行传递,然后接收方再进行反序列化,还原这个对象实例。下面的示例代码演示了如何传递数组与类(接口)类型的数据,并演示如何使用字节数组上传图像。本示例的客户端代码使用Java编写。要完成这个例子需要如下几步:一、实现服务端代码[java]viewplaincopy<spanstyle="font-size:14px;">importjava.io.FileOutputStream;importdata.DataForm;publicclassComplexTypeService{//上传图像,imageByte参数表示上传图像文件的字节,//length参数表示图像文件的字节长度(该参数值可能小于imageByte的数组长度)publicbooleanuploadImageWithByte(byte[]imageByte,intlength){FileOutputStreamfos=null;try{//将上传的图像保存在D盘的test1.jpg文件中fos=newFileOutputStream("d:\\test1.jpg");//开始写入图像文件的字节fos.write(imageByte,0,length);fos.close();}catch(Exceptione){returnfalse;}finally{if(fos!=null){try{fos.close();}25.PNG"></span></p>四、使用Java编写调用WebService的客户端代码在客户端仍然使用了RPC的调用方式,代码如下:[java]viewplaincopy<spanstyle="font-size:14px;">packageclient;importspace.QName;importorg.apache.axis2.addressing.EndpointReference;importorg.apache.axis2.client.Options;importorg.apache.axis2.rpc.client.RPCServiceClient;publicclassComplexTypeRPCClient{publicstaticvoidmain(String[]args)throwsException{RPCServiceClientserviceClient=newRPCServiceClient();Optionsoptions=serviceClient.getOptions();EndpointReferencetargetEPR=newEndpointReference("http://localhost:8080/axis2/services/ComplexTypeService");options.setTo(targetEPR);//下面的代码调用uploadImageWithByte方法上传图像文件//打开图像文件,确定图像文件的大小java.io.Filefile=newjava.io.File("f:\\images.jpg");java.io.FileInputStreamfis=newjava.io.FileInputStream("f:\\images.jpg");//创建保存要上传的图像文件内容的字节数组byte[]buffer=newbyte[(int)file.length()];//将图像文件的内容读取buffer数组中intn=fis.read(buffer);System.out.println("文件长度:"+file.length());Object[]opAddEntryArgs=newObject[]{buffer,n};Class[]classes=newClass[]{Boolean.class};QNameopAddEntry=newQName("/axis2","uploadImageWithByte");fis.close();//开始上传图像文件,并输出uploadImageWithByte方法的返回传System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs,classes)[0]);//下面的代码调用了getArray方法,并返回一维String数组opAddEntry=newQName("/axis2","getArray");String[]strArray=(String[])serviceClient.invokeBlocking(opAddEntry,newObject[]{},newClass[]{String[].class})[0];for(Strings:strArray)System.out.print(s+"");System.out.println();//下面的代码调用了getMDArray方法,并返回一维String数组opAddEntry=newQName("/axis2","getMDArray");strArray=(String[])serviceClient.invokeBlocking(opAddEntry,newObject[]{},newClass[]{String[].class})[0];for(Strings:strArray){String[]array=s.split(",");for(Stringss:array)System.out.print("<"+ss+">");System.out.println();}System.out.println();//下面的代码调用了getDataForm方法,并返回DataForm对象实例opAddEntry=newQName("/axis2","getDataForm");data.DataFormdf=(data.DataForm)serviceClient.invokeBlocking(opAddEntry,newObject[]{},newClass[]{data.DataForm.class})[0];System.out.println(df.getAge());//下面的代码调用了getDataFormBytes方法,并返回字节数组,最后将返回的字节数组反序列化后,转换成DataForm对象实例opAddEntry=newQName("/axis2","getDataFormBytes");buffer=(byte[])serviceClient.invokeBlocking(opAddEntry,newObject[]{},newClass[]{byte[].class})[0];java.io.ObjectInputStreamois=newjava.io.ObjectInputStream(newjava.io.ByteArrayInputStream(buffer));df=(data.DataForm)ois.readObject();System.out.println(df.getName());}}</span>运行上面的程序,将输出如下的内容:文件长度:3617true自行车飞机火箭<自行车><飞机><火箭><中国><美国><德国><超人><蜘蛛侠><钢铁侠>20如果读者要上传大文件,应尽量使用FTP的方式来传递,而只通过WebService方法来传递文件名等信息。这样有助于提高传输效率。以上的就是教程上的,照猫画虎,没什么技术含量,几分钟搞定,唯一需要的就是对java的io包,及java的输入输出要熟悉,不然就比较麻烦了。虽说自己懂了,但是看着客户端代码,我不禁问自己,调用webservice难道就这么复杂吗,有着现成的wsdl2java.bat我们为什么不用呢,难道教程上没有的我们就不学了吗?教程上的就一定是最好的吗?带着这些问题我开始了探索之旅,废话少说,看招!生成stub类的方法我就不多讲了,不懂得朋友可以去看我的上一篇文章点击打开链接,引入生成的stub类,这个类是通过wsdl文件转化而来的,它把发布到webservice的方法封装成了类,把方法的参数封装成了方法(就像javabean一样的set方法一样),但是用当前类的对象去访问这个stub类的时候又是我们平常所熟悉的那样,没变,估计这么说也不明白,直接上代码。[java]viewplaincopy<spanstyle="font-size:14px;">packageclient;importjava.io.ByteArrayInputStream;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.rmi.RemoteException;importjavax.activation.DataHandler;importjavax.activation.DataSource;importdata.DataForm;publicclassComplexStubClient{publicstaticvoidmain(String[]args)throwsException{ComplexTypeServiceStubstub=newComplexTypeServiceStub();ComplexTypeServiceStub.GetArrayga=newComplexTypeServiceStub.GetArray();ComplexTypeServiceStub.GetDataFormgdf=newComplexTypeServiceStub.GetDataForm();ComplexTypeServiceStub.GetDataFormBytesgdfb=newComplexTypeServiceStub.GetDataFormBytes();ComplexTypeServiceStub.GetMDArraygmda=newComplexTypeServiceStub.GetMDArray();ComplexTypeServiceStub.UploadImageWithByteuiwb=newComplexTypeServiceStub.UploadImageWithByte();upload(stub,uiwb);arrayOD(stub,ga);arrayMD(stub,gmda);dataForm(stub,gdf);dataFormByte(stub,gdfb);}publicstaticvoiddataFormByte(ComplexTypeServiceStubstub,ComplexTypeServiceStub.GetDataFormBytesgdfb)throwsRemoteException,ComplexTypeServiceExceptionException,IOException,ClassNotFoundException{DataHandlerdh=stub.getDataFormBytes(gdfb).get_return();//System.out.println(dh.getContent().getClass());DataSourceds=dh.getDataSource();java.io.ObjectInputStreamois=newjava.io.ObjectInputStream(ds.getInputStream());DataFormdf=(data.DataForm)ois.readObject();System.out.println(df.getName());}publicstaticvoiddataForm(ComplexTypeServiceStubstub,ComplexTypeServiceStub.GetDataFormgdf)throwsRemoteException{client.ComplexTypeServiceStub.DataFormdf=stub.getDataForm(gdf).get_return();//对象实例System.out.println(df.getAge()+""+df.getName());//变量}publicstaticvoidarrayMD(ComplexTypeServiceStubstub,ComplexTypeServiceStub.GetMDArraygmda)throwsRemoteException{String[]strArry=stub.getMDArray(gmda).get_return();for(Strings:strArry){String[]str=s.split(",");for(Strings2:str){System.out.print(s2+"");}System.out.print("");}System.out.println();}publicstaticvoidarrayOD(ComplexTypeServiceStubstub,ComplexTypeServiceStub.GetArrayga)throwsRemoteException{String[]strArry=stub.getArray(ga).get_return();for(Strings:strArry){System.out.print(s+"");}System.out.println();}publicstaticvoidupload(ComplexTypeServiceStubstub,ComplexTypeServiceStub.UploadImageWithByteuiwb)throwsFileNotFoundException,IOException,RemoteException{Filefile=newFile("f:\\images.jpg");FileInputStreamfis=newFileInputStream("f:\\images.jpg");//创建保存要上传的图像文件内容的字节数组finalbyte[]buffer=newbyte[(int)file.length()];intn=fis.read(buffer);System.out.println("文件长度:"+file.length());uiwb.setLength(n);uiwb.setImageByte(newDataHandler(newDataSource(){publicInputStreamgetInputStream(){returnnewByteArrayInputStream(buffer);}publicOutputStreamgetOutputStream(){returnnull;}publicStringgetContentType(){return"";}publicStringgetName(){return"";}}));System.out.println(stub.uploadImageWithByte(uiwb).get_return());}}</span>在这个方法里应该着重强调的是upload(stub,uiwb);和dataFormByte(stub,gdfb);upload(stub,uiwb);中setImageByte()方法中的参数在服务器端是字节数组类型的,但是到了stub类中奇迹般的变成了DataHandler类型,而这个类型是jdk1.6才有的,如下式API文档的介绍DataHandler类为在多种不同源和格式下可用的数据提供一致的接口。它使用DataContentHandler管理简单流到字符串的转换以及相关操作。它提供对能够操作数据的命令的访问。使用CommandMap可以找到这些命令。有兴趣的可以自己去查一下,为了把字节数组转换成这种类型,我花了九牛二虎之力才达到,居然是要通过两层转化,还是内部类,哎,坑爹啊。如下图所示最坑爹的还不是这个,到了dataFormByte(stub,gdfb);方法中又需要把DataHandler类型转化成字节数组类型,你说这不是耍我吗,就是这一耍,搞了我两个小时,不过从结果来看被耍的还是值的,哈哈,人怎么就这么贱呢。[java]viewplaincopy<spanstyle="font-size:14px;">DataHandlerdh=stub

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论