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());
}
集合:返回集合的解决思路,就是将集合使用对象进行封装,然后返回封装后的对象,在客户端接收到对象后,从对象中取出集合。