axis2系列之传输复杂类型的数据

eclipse开发环境搭建可参考:axis2系列之eclipse开发环境搭建

编写hello world程序可参考:axis2系列之HelloWorld

复杂数据类型操作主要有两个方面:1、参数传递2、返回值

参数传递:自定义类、表单提交(上传文件等)、数组(在文件上传中都有体现)、集合

返回值:数组、自定类、集合等

一、参数传递:

(1)、自定义类:
自定义类如下:
package com.test;

public class Person {

	private long id;
	private String name;
	private int age;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	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;
	}
	
	public String toString(){
		return "姓名:"+this.name+",年龄:"+this.age;
	}
	
}
service服务端方法如下:

/**
	 * 参数传递自定义类型
	 * @param person
	 * @return
	 */
	public boolean savePerson(Person person){
		if(person == null){
			return false;
		}
		System.out.println(person);
		return true;
	}
services.xml文件配置如下:

services.xml文件内容与普通的web service配置一致。

service客户端方法如下:
public static void main(String[] args) {
		try {
			EndpointReference targetEPR = new EndpointReference(
					"http://localhost:8080/mywebservice/services/complexService");
			RPCServiceClient serviceClient = new RPCServiceClient();
			Options options = serviceClient.getOptions();
			options.setTo(targetEPR);

			QName opGetWeather = new QName("http://test.com",
					"savePerson");
			
			Person person = new Person();
			person.setId(1L);
			person.setName("张三");
			person.setAge(22);
			
			Object[] opGetWeatherArgs = new Object[] {person};
			Class[] returnTypes = new Class[] { boolean.class };
			Object[] response = serviceClient.invokeBlocking(opGetWeather,
					opGetWeatherArgs, returnTypes);
			System.out.println(response[0]);
		} catch (AxisFault e) {
			e.printStackTrace();
		}
	}

执行结果如下:
服务器端:

客户端:

(2)、上传二进制文件
服务端如下:
/**
 * axis2 二进制文件传输
 * @author Administrator
 * 
 * axis2 传输二进制文件有两种方式
 * 	第一种:使用byte[]数组类型,进行数据的传输
 * 	第二种:使用DataHandler类型,进行数据的传输
 *
 */
public class BinaryFileService {

	//使用byte[]类型参数上传二进制文件
	//file 上传文件二进制数据
	//targetFile 目标文件路径
	public boolean uploadWithByte(byte[] file,String targetFile){
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(targetFile);
			fos.write(file);
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}finally{
			if(fos != null){
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return true;
	}
	
	//使用DataHandler类型参数,进行二进制文件的传输
	public boolean uploadWithDataHandler(DataHandler file,String targetFile){
		FileOutputStream fos = null;
		InputStream fis = null;
		try {
			fos = new FileOutputStream(targetFile);
			fis = file.getInputStream();
			
			int len = 0;
			byte[] buffer = new byte[1024];
			while((len = fis.read(buffer)) > 0){
				fos.write(buffer, 0, len);
			}
			fis.close();
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}finally{
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if(fos != null){
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return true;
	}
}
客户端如下:
public static void main(String[] args) {
		RPCServiceClient client = null;
		try {
			client = new RPCServiceClient();
			Options options = client.getOptions();
			EndpointReference targetEPR = new EndpointReference("http://localhost:8080/myservice/services/binaryFileService");
			options.setTo(targetEPR);
			
			//调用uploadWithByte方法
			String srcFilePath = "d:\\pxt.jpg";
			String targetFilePath1 = "d:\\test2.jpg";
			String targetFilePath2 = "d:\\test3.jpg";
			
			File file = new File(srcFilePath);
			FileInputStream fis = new FileInputStream(file);
			byte[] buffer = new byte[(int) file.length()];
			fis.read(buffer);
			fis.close();
			//qName
			//byte[]方式
			QName qName = new QName("http://service.binaryFile.test.com","uploadWithByte");
			Object[] oArgs = new Object[]{buffer,targetFilePath1};
			Class[] cRtnType = new Class[]{Boolean.class};
			Boolean isUpload = (Boolean) client.invokeBlocking(qName, oArgs, cRtnType)[0];
			System.out.println(isUpload);
			
			//DataHandler方式
			DataHandler handler = new DataHandler(new FileDataSource(srcFilePath));
			qName = new QName("http://service.binaryFile.test.com","uploadWithDataHandler");
			oArgs = new Object[]{handler,targetFilePath2};
			cRtnType = new Class[]{Boolean.class};
			isUpload = (Boolean) client.invokeBlocking(qName, oArgs, cRtnType)[0];
			System.out.println(isUpload);
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

(3)、集合
由于web service 设计师跨语言的,有的语言有集合,有的语言是没有集合的,因此,直接传递集合,web service 是不支持的,所以有两种解决方案:
1、将集合转化为数组,以list集合为例,然后以数组的方式传递,在服务器端接收也必须接收的是数组。
List<String> list = new ArrayList<String>();
String[] strArr = list.toArray(new String[list.size()]);
2、创建自定义类,将集合进行封装,然后以自定类的形式进行参数的传递。
package com.test;

import java.util.List;

public class User {

	private List<String> list;

	public List<String> getList() {
		return list;
	}

	public void setList(List<String> list) {
		this.list = list;
	}
	
}
List<String> list = new ArrayList<String>();
user.setList(list);

二、返回值

(1)、数组(一维数组、二维数组)

服务器端:

//返回一维字符串数组
	public String[] getArray(){
		String[] strArr = new String[]{"自行车","飞机","火箭"};
		return strArr;
	}
客户端:

//调用返回一维数组的方法
			entryArgs = new Object[]{};
			classes = new Class[]{String[].class};
			qName = new QName("http://service.complesType.test.com","getArray");
			String[] strValue = (String[])serviceClient.invokeBlocking(qName, entryArgs, classes)[0];
			if(strValue != null && strValue.length > 0){
				for(int i = 0; i < strValue.length ; i ++){
					System.out.println(strValue[i]);
				}
			}
二维数组:

同样,有的语言中没有二维数组这个概念,因此web service 也是不支持的,解决思路是:将二维数组转化为一维数组,如果是字符串,可以将二维数组的第一维度,转化为一个字符串,每个值使用","隔开,如果是其他类型,可以将二维数组的第一维度使用对象进行封装(或者直接将二维数组使用对象进行封装)。

字符串二维数组-服务器端:

//返回二维字符串数组
	public String[] getMDArray(){
		String[] strArr = new String[]{"自行车,飞机,火箭","中国,美国,德国","超人,蜘蛛侠,钢铁侠"};
		return strArr;
	}

字符串二维数组-客户端:

//调用返回二维数组的方法
			entryArgs = new Object[]{};
			classes = new Class[]{String[].class};
			qName = new QName("http://service.complesType.test.com","getMDArray");
			String[] strVal = (String[])serviceClient.invokeBlocking(qName, entryArgs, classes)[0];
			if(strVal != null && strVal.length > 0){
				for(int i = 0; i < strVal.length ; i ++){
					String[] strs = strVal[i].split(",");
					for(int j = 0; j < strs.length; j ++){
						System.out.print(strs[j]);
						System.out.print("  ");
					}
					System.out.println();
				}
			}
其他类型二维数组-服务器端
package com.test;

public class IntDDR {

	private Integer[] intArr;

	public Integer[] getIntArr() {
		return intArr;
	}

	public void setIntArr(Integer[] intArr) {
		this.intArr = intArr;
	}
	
}
//其他类型的二维数组:比如整数类型
	public IntDDR[] getDDRArray(){
		Integer[] intArr1 = new Integer[]{1,2,3,4};
		Integer[] intArr2 = new Integer[]{1,2,3,4};
		
		
		IntDDR ddr1 = new IntDDR();
		ddr1.setIntArr(intArr1);
		IntDDR ddr2 = new IntDDR();
		ddr1.setIntArr(intArr2);
		
		IntDDR[] ddr = new IntDDR[]{ddr1,ddr2};
		
		return ddr;
		
	}

其他类型二维数组-客户端:

		
			Object[] opGetWeatherArgs = new Object[] {};
			Class[] returnTypes = new Class[] { IntDDR[].class };
			IntDDR[] response = (IntDDR[]) serviceClient.invokeBlocking(opGetWeather,
					opGetWeatherArgs, returnTypes)[0];
			for(int i = 0; i < response.length; i ++){
					IntDDR ddr =  response[i];
					Integer[] intArr = ddr.getIntArr();
					for(int j = 0; j < intArr.length; j ++){
						System.out.println(intArr[j]);
					}
				}

自定义类:

服务器端

//返回DataForm类的对象实例
	public DataForm getDataFrom(){
		return new DataForm();
	}
客户端:

	//返回DataForm实例对象
			entryArgs = new Object[]{};
			classes = new Class[]{DataForm.class};
			qName = new QName("http://service.complesType.test.com","getDataFrom");
			DataForm dataForm =(DataForm) serviceClient.invokeBlocking(qName, entryArgs, classes)[0];
			if(dataForm != null){
				System.out.println("姓名:"+dataForm.getName());
				System.out.println("年龄:"+dataForm.getAge());
			}

集合:返回集合的解决思路,就是将集合使用对象进行封装,然后返回封装后的对象,在客户端接收到对象后,从对象中取出集合。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值