三、复杂类型数据的传递
不多说,先上服务端的代码,有前面的基础看懂应该没问题
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数组的方式可以获取到list
opAddEntry = 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();
//调用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,但是我尝试之后无效。