WebServices学习笔记(三)复杂类型数据的传递

来源:互联网 发布:wpf高级编程 pdf 网盘 编辑:程序博客网 时间:2024/06/07 06:38

三、复杂类型数据的传递

不多说,先上服务端的代码,有前面的基础看懂应该没问题

import java.io.FileOutputStream;import java.io.IOException;import java.util.LinkedList;import java.util.List;public class ComplexTypeService {//  上传图像,imageByte参数表示上传图像文件的字节,    //  length参数表示图像文件的字节长度(该参数值可能小于imageByte的数组长度)public boolean uploadImageWithByte(byte[] imageByte, int length){FileOutputStream fos = null;try{fos = new FileOutputStream("D:\\test1.jpg");fos.write(imageByte, 0, length);fos.close();}catch(Exception e){return false;}finally{if(fos!=null){try {fos.close();} catch (IOException e) {e.printStackTrace();}}}return true;}    public String[] getArray()    {        String[] strArray = new String[]{"china","原来乱码是JAVA文件默认编码集的问题","不"};        return strArray;    }            public DataForm getDataForm()    {        return new DataForm();    }        //  将DataForm类的对象实例序列化,并返回序列化后的字节数组    public byte[] getDataFormBytes() throws Exception     {        java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();        java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(baos);        oos.writeObject(new DataForm());        return baos.toByteArray();    }    //返回DataForm对象数组    public DataForm[] getDataFormArray() throws IOException{    DataForm d1 = new DataForm(),    d2 = new DataForm();    d2.setName("尼玛");    d2.setAge(19);        return new DataForm[]{d1,d2};    }    //序列化的对象中包含一个List    public byte[] getDataFormList() throws IOException{    DataForm d1 = new DataForm(),    d2 = new DataForm();    d2.setName("我");    d2.setAge(19);        List<DataForm> list = new LinkedList<DataForm>();    list.add(d1);    list.add(d2);        d2.setList(list);    java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();        java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(baos);        oos.writeObject(d2);        return baos.toByteArray();    }    //直接返回List    public List<DataForm> getDataFormList2() throws IOException{    DataForm d1 = new DataForm(),    d2 = new DataForm();    d2.setName("草泥马");    d2.setAge(19);        List<DataForm> list = new LinkedList<DataForm>();    list.add(d1);    list.add(d2);        return list;    }}

实体类DataForm

import java.util.List;public class DataForm implements java.io.Serializable{//这个对象包含了一个List,作为webservice返回泛型集合的一种方法List<DataForm> list;    public List<DataForm> getList() {return list;}public void setList(List<DataForm> list) {this.list = list;}private String name = "bill";    private int age = 20;    public String getName()    {        return name;    }    public void setName(String name)    {        this.name = name;    }    public int getAge()    {        return age;    }    public void setAge(int age)    {        this.age = age;    }}

接下来是客户端

import java.io.File;import java.io.FileInputStream;import java.io.IOException;import javax.activation.DataHandler;import javax.activation.DataSource;import javax.xml.namespace.QName;import org.apache.axis2.addressing.EndpointReference;import org.apache.axis2.client.Options;import org.apache.axis2.rpc.client.RPCServiceClient;import complex.ComplexTypeServiceIOExceptionException;import complex.ComplexTypeServiceStub;public class ComplexTypeRPCClient {public static void main(String[] args) throws IOException,ClassNotFoundException, ComplexTypeServiceIOExceptionException {String url = "http://125.216.247.15:8080/axis2/services/ComplexTypeService";String ns = "http://ws.apache.org/axis2";RPCServiceClient serviceClient = new RPCServiceClient();Options options = serviceClient.getOptions();EndpointReference targetEPR = new EndpointReference(url);options.setTo(targetEPR);/*************** 下面的代码调用uploadImageWithByte方法上传图像文件 **********/// 打开图像文件,确定图像的大小File file = new File("D:\\1.jpg");FileInputStream fis = new FileInputStream(file);// 创建保存要上传的图像文件内容的字节数组byte[] buffer = new byte[(int) file.length()];// 将图像文件的内容读取buffer数组中int n = fis.read(buffer);System.out.println("文件长度:" + n);Object[] opAddEntryArgs = new Object[] { buffer, n };Class[] classes = new Class[] { Boolean.class };QName opAddEntry = new QName(ns, "uploadImageWithByte");fis.close();// 开始上传图像文件,并输出uploadImageWithByte方法的返回传System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs, classes)[0]);/**********************************************************///这一段调用用RPC方法调用getArray获取String数组opAddEntry = new QName("http://ws.apache.org/axis2", "getArray");String[] strArray = (String[]) serviceClient.invokeBlocking(opAddEntry,new Object[] {}, new Class[] { String[].class })[0];for (String s : strArray)System.out.print(s + "  ");System.out.println();//这一段调用用RPC方法调用getDataFormList获取包含一个List的DataForm对象//奇怪的是df.getList()得到的是null,而下面返回byte数组的方式可以获取到listopAddEntry = new QName("http://ws.apache.org/axis2", "getDataFormList");DataForm df = (DataForm) serviceClient.invokeBlocking(opAddEntry,new Object[] {}, new Class[] { DataForm.class })[0];System.out.println(df.getList()+df.getName()+df.getAge());//这一段调用用RPC方法调用getDataFormList以byte数组形式获取DataForm对象opAddEntry = new QName("http://ws.apache.org/axis2", "getDataFormBytes");buffer = (byte[]) serviceClient.invokeBlocking(opAddEntry,new Object[] {}, new Class[] { byte[].class })[0];java.io.ObjectInputStream ois = new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(buffer));df = (DataForm) ois.readObject();System.out.println(df.getName());//与上面类似opAddEntry = new QName("http://ws.apache.org/axis2", "getDataFormList");buffer = (byte[]) serviceClient.invokeBlocking(opAddEntry, new Object[]{}, new Class[]{byte[].class})[0];java.io.ObjectInputStream ois2 = new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(buffer));df = (DataForm) ois2.readObject();System.out.println(df.getList()+df.getName()+df.getAge());//下面是借用wsdl2java工具生成的代码编写的,都能获取到完整的对象ComplexTypeServiceStub stub = new ComplexTypeServiceStub();//调用GetDataFormArrayComplexTypeServiceStub.GetDataFormArray g2 = new ComplexTypeServiceStub.GetDataFormArray();        complex.ComplexTypeServiceStub.DataForm[] dfArr = stub.getDataFormArray(g2).get_return();System.out.println(df.getList()+df.getName()+df.getAge());//调用GetDataFormList2,可以直接获取到List,不过也是获取到对象数组,估计中间进行了转换ComplexTypeServiceStub.GetDataFormList2 g1 = new ComplexTypeServiceStub.GetDataFormList2();        dfArr = stub.getDataFormList2(g1).get_return();System.out.println(df.getList()+df.getName()+df.getAge());//调用GetDataFormList,这种方法返回的对象是DataHandler,可以成功获取ComplexTypeServiceStub.GetDataFormList g3 = new ComplexTypeServiceStub.GetDataFormList();        DataHandler dh = stub.getDataFormList(g3).get_return();        DataSource ds = dh.getDataSource();          ois = new java.io.ObjectInputStream(ds.getInputStream());          df = (DataForm) ois.readObject();  System.out.println(df.getList()+df.getName()+df.getAge());}}


通过上面的代码可以看到,获取普通对象的方法有两种,一种是直接获取,一种是转换成byte数组后再转换成对象。

为了能够获取到泛型集合,如,我在DataForm类里面加了一个List<DataForm>类型的成员,并尝试了不同的方法去获取,总结如下:

1. 直接返回DataForm对象的方法:无法获取到List<DataForm>,其他成员可正常获取,原因我暂时还不清楚,有人知道的话请指教!

2. 通过byte[]返回DataForm对象的方法:可以正常获取

3. 通过byte[]返回List<DataForm>的方法,会报堆栈溢出的错误,暂时也不清楚原因。

4. 对于直接返回DataForm[]和List<DataForm>的方法,采用wsdl2java生成的代码,可以成功获取到DataForm[]。

5. wsdl2java对于返回byte[]的方法,处理后返回的对象是DataHandler,这个时候需要从DataHandler里面获取数据源,再从数据源获取输入流转换成对象


最后是传参乱码的问题,而且是tomcat重启后就乱码。我发现是java文件默认编码的问题,我的myeclipse上默认编码是UTF-8,

在Windows->Preferences->General->Content  Types->Text->Java source file,把默认编码集改成GBK(因为在我的系统上,

通过这个网页可以看到:http://localhost:8080/axis2/axis2-web/HappyAxis.jsp,默认file.encoding=GBK)


网上也有人说在tomcat的catalina.bat中加上set CATALINA_OPTS=-Dfile.encoding=GBK,但是我尝试之后无效。

0 0
原创粉丝点击