初步搞定:(服务如何发布就不详细说了,网上很多) 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));
这是发布到服务器上面的代码:
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呢?
能不能说得细一点啊,不太明白啊!
ArrayList不符合Bean规则.按你上面的client代码,axis会调用bean的序列化/反序列化器.
解决办法是设定使用的序列化/反序列化器.axis好像有ArrayList的序列化/反序列化器.或者自己实现序列化/反序列化器.
做了以上的事以后你还需要把所有ArrayList中可能存在的Object类型全部注册.不然还会报错.太麻烦.所以最好不要返回ArrayList类型的数据.可以自己写个类用于传递数据.
修正为
public List myAL()
那一个public ArrayList myAL()改动啊?是服务器上面的吗?那不是把服务返回类型都变了啊!
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>
这一版没有把它写成服务\客户端的形式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();
}
}