WebServices学习笔记(三)复杂类型数据的传递
三、复杂类型数据的传递 不多说,先上服务端的代码,有前面的基础看懂应该没问题
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,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数组的方式可以获取到list opAddEntry = new QName("http://ws.apache.org/axis2","getDataFormList"); DataForm df = (DataForm) serviceClient.invokeBlocking(opAddEntry,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 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(); //调用GetDataFormArray ComplexTypeServiceStub.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,但是我尝试之后无效。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |