一个服务返回一个ArrayList,如何使用Axis序列化/反序列化啊

zzmdegm 2007-01-08 11:17:14
我的代码如下:
这是发布到服务器上面的代码:
package com;
import java.util.*;
public class ArrayListService {
public ArrayList myAL(){
ArrayList<String> myAL = new ArrayList<String>();
String str=new String("这是一个WebService Of ArrayList !");
myAL.add(str);
return myAL;
}}

客户端的代码:
package com;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import java.util.*;

public class ArrayListClient {
public static void main(String[] args) {
try {
String wsdlUrl = "http://127.0.0.1:8080/axis/services/ArrayListService?wsdl";

Service service = new Service();
Call call = null;
call = (Call) service.createCall();

call.setOperationName("myAL");
call.setTargetEndpointAddress(new java.net.URL(wsdlUrl));
//ArrayList al=(ArrayList)call.invoke(new Object[] {});
call.invoke(new Object[] {});
System.out.println("请求信息:");
call.getMessageContext().getRequestMessage().writeTo(System.out);
System.out.println("");
System.out.println("响应信息:");
call.getMessageContext().getResponseMessage().writeTo(System.out);
System.out.println("");
}
catch (Exception ex) { ex.printStackTrace(); }}}
打印出来的请求和响应消息也正常。
可是服务器返回的是一个ArrayList,当用这一句时“ArrayList al=(ArrayList)call.invoke(new Object[] {});”就报错:
java.lang.ClassCastException: [Ljava.lang.Object;
at com.ArrayListClient.main(ArrayListClient.java:17)
这是什么原因啊,如何把响应消息里面的数据返回成ArrayList呢?

注:server-config.wsdd
<service name="ArrayListService" provider="java:RPC">
<parameter name="className" value="com.ArrayListService"/>
<parameter name="allowedMethods" value="*"/>
<requestFlow>
<handler type="loging"/>
</requestFlow>
<responseFlow>
<handler type="loging"/>
</responseFlow>
</service>

这是服务响应消息:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<myALResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<myALReturn href="#id0"/>
</myALResponse>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" soapenc:arrayType="xsd:anyType[1]" xsi:type="soapenc:Array" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<multiRef xsi:type="soapenc:string">这是一个WebService Of ArrayList !</multiRef>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
...全文
342 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
sharkzsy 2008-07-14
  • 打赏
  • 举报
回复
一个人在这折腾。。。
yohomonkey 2007-01-19
  • 打赏
  • 举报
回复
呵呵!
zzmdegm 2007-01-19
  • 打赏
  • 举报
回复
正解:
这一版没有把它写成服务\客户端的形式

package com;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.*;

public class ArrayListSerializ implements Serializable{
/**
* 此例是一个序列化/反序列化的方法 :
*
* 主要思想是把一个对象写入对象输出流,然后把这个流里面的数据导入字节数组输出流
* 再把字节数组输出流导入到字节数组。这时,由于byte[]数组是从ObjectOutputStream之后得来的,
* 那么是不可以new String(buff)的,因为其中包含了不可见字符,根本不是一个字符串。
* 只能用sun.misc.BASE64Encoder把它翻译成字符串形式。
* 至此,这就完成了序列化成字符串行式的过程
*
* 再通过sun.misc.BASE64Decoder().decodeBuffer把字符串转换成一个byte[],
* 然后通过其反思路完成反序列化过程
*/
private static final long serialVersionUID = 1L;
private static void myArrayListSerializer()
{
ArrayList<String> myAL=new ArrayList<String>();
myAL.add("This is a serial programme.author: 张正明");
System.out.println("ArrayList's content: "+myAL.get(0));
//序列化使用的输出流
ObjectOutputStream OOS=null;
//序列化后数据流给ByteArrayOutputStream 来保存。
//ByteArrayOutputStream 可转成字符串或字节数组
ByteArrayOutputStream BAOS=new ByteArrayOutputStream();
//ByteArrayInputStream 可接收一个字节数组"byte[]"。供反序列化做参数
ByteArrayInputStream BAIS=null;
//反序列化使用的输入流
ObjectInputStream OIS=null;
try {
OOS=new ObjectOutputStream(BAOS);
OOS.writeObject(myAL);
byte[] buff=BAOS.toByteArray();

/*由于byte[]数组是从ObjectOutputStream之后得来的,
*那么是不可以new String(buff)的,因为其中包含了不可见字符,根本不是一个字符串
*/
System.out.println("序列化成一个byte[]的字符串形式 :"+buff);
//转换成字符串
sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
String Sstr = encoder.encode(buff);
System.out.println("序列化成一个字符串:"+Sstr);
System.out.println("检查序列化成一个字符串和序列化成一个byte[]是否为同一个内容:"+
Arrays.equals(buff, new sun.misc.BASE64Decoder().decodeBuffer(Sstr)));
OOS.close();

// 把字符串转成一个byte[]
byte[] DSbuff=new sun.misc.BASE64Decoder().decodeBuffer(Sstr);
System.out.println("反序列化成一个byte[]字符串形式 :"+DSbuff);
//实现反序列化
BAIS=new ByteArrayInputStream(DSbuff);
OIS=new ObjectInputStream(BAIS);
ArrayList c=(ArrayList)(OIS.readObject());
System.out.println("反序列化后取提ArrayList的数据: "+c.get(0));
OIS.close();
}
catch (IOException e) {e.printStackTrace();}
catch (Exception ex) {System.out.println("序列化时产生错误");}
}
public static void main(String[] args){
myArrayListSerializer();
}
}
zzmdegm 2007-01-10
  • 打赏
  • 举报
回复
arrayList ,victor,set,map传输在j2ee web service标准里是有限制的 ,改用数组

初步搞定:(服务如何发布就不详细说了,网上很多)
java程序用 Axis做服务时自定义类实体的传送

核心代码:
QName qn = new QName("urn:BeanService","MyArryBean");
call.registerTypeMapping(MyArryBean.class, qn,
new BeanSerializerFactory(MyArryBean.class, qn),
new BeanDeserializerFactory(MyArryBean.class, qn));
这是在客户机端的代码,用于注册服务器上面的自定义类。然后就可以在客户端实例化这个类来使用。(如果MyArryBean 与服

务类不在同一个包里面,即服务需要用 import 来引用的话,这时就要用到 :包名.MyArryBean.class)

在Axis服务端,注册自定义对象的序列化/反序列化器
服务器的server-config.wsdd:
...
<service name="ArrayListService" provider="java:RPC">
<parameter name="className" value="com.ArrayListService"/>
<parameter name="allowedMethods" value="*"/>
<beanMapping languageSpecificType="java:com.MyArryBean" qname="ns:MyArryBean" xmlns:ns="urn:BeanService"/>
<requestFlow>
<handler type="loging"/>
</requestFlow>
<responseFlow>
<handler type="loging"/>
</responseFlow>
</service>
...

服务器上面的自定义类(这个类要被传递给客户端):MyArryBean.java
package com;
import java.io.Serializable;

public class MyArryBean implements Serializable{
private static final long serialVersionUID = -6414428095965735488L;
private String str="";
public MyArryBean(){}
public void setBean(String str){this.str=str;}
public String getBean(){return this.str;}
}

服务器上面的服务类:ArrayListService.java
package com;

public class ArrayListService {
//这里返回的是一个int数组
public int[] myAL(){
int myAL[] = new int[5];
for( int i=0;i<5;i++){
myAL[i]=i;
}
return myAL;
}
//这里返回的是一个自定义对象
public MyArryBean myAB(String myStr){
MyArryBean _myArryB=new MyArryBean();
_myArryB.setBean(myStr);
return _myArryB;
}
}

客户端代码:ArrayListClient.java
package com;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import javax.xml.namespace.QName;

public class ArrayListClient {
public static void main(String[] args) {
try {
String wsdlUrl = "http://127.0.0.1:8080/axis/services/ArrayListService?wsdl";
String nameSpaceUri = "http://localhost:8080/axis/services/ArrayListService";

Service service = new Service();
Call call = null;
call = (Call) service.createCall();

//注册MyArryBean的序列化类型
QName qn = new QName("urn:BeanService","MyArryBean");
call.registerTypeMapping(MyArryBean.class, qn,
new BeanSerializerFactory(MyArryBean.class, qn),
new BeanDeserializerFactory(MyArryBean.class, qn));

//这里取得的是一个服务器int数组
call.setOperationName("myAL");
call.setTargetEndpointAddress(new java.net.URL(wsdlUrl));
int[] _resp = (int[])call.invoke(new java.lang.Object[] {});
for (int i=0;i<5;i++){
System.out.println("int数组:"+_resp[i]);
}

//这里取得的是一个服务器自定义对象
//这里实例化服务器上面的映射的自定义类
MyArryBean CmyAB=new MyArryBean();
CmyAB.setBean("这是的客户端实例化服务器的类!yes");
System.out.println("return value is " + CmyAB.getBean());
QName getmyABQn = new QName(nameSpaceUri, "myAB");
call.setOperationName(getmyABQn);
call.setTargetEndpointAddress(new java.net.URL(wsdlUrl));
CmyAB = (MyArryBean) call.invoke(new Object[] { "这是调用服务器的类!web" });
System.out.println("return value is " + CmyAB.getBean());

System.out.println("请求信息:");
call.getMessageContext().getRequestMessage().writeTo(System.out);
System.out.println("");
System.out.println("响应信息:");
call.getMessageContext().getResponseMessage().writeTo(System.out);
System.out.println("");
}
catch (Exception ex) { ex.printStackTrace(); }}}


运行结果:

int数组:0
int数组:1
int数组:2
int数组:3
int数组:4
return value is 这是的客户端实例化服务器的类!yes
return value is 这是调用服务器的类!web
请求信息:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:myAB soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:ns1="http://localhost:8080/axis/services/ArrayListService">
<ns1:arg0 xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
这是调用服务器的类!web
</ns1:arg0>
</ns1:myAB>
</soapenv:Body>
</soapenv:Envelope>
响应信息:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:myABResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:ns1="http://localhost:8080/axis/services/ArrayListService">
<myABReturn href="#id0"/>
</ns1:myABResponse>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

xsi:type="ns2:MyArryBean" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:ns2="urn:BeanService">
<bean xsi:type="soapenc:string">
这是调用服务器的类!web
</bean>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>

23,407

社区成员

发帖
与我相关
我的任务
社区描述
Java 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧