rt

解决方案 »

  1.   

    我的代码如下:
    这是发布到服务器上面的代码:
    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呢?
      

  2.   

    to:mdxk(一笑家园)
    能不能说得细一点啊,不太明白啊!
      

  3.   

    这个问题我也遇到过.当时的技术调查结果是这样的.
    ArrayList不符合Bean规则.按你上面的client代码,axis会调用bean的序列化/反序列化器.
    解决办法是设定使用的序列化/反序列化器.axis好像有ArrayList的序列化/反序列化器.或者自己实现序列化/反序列化器.
    做了以上的事以后你还需要把所有ArrayList中可能存在的Object类型全部注册.不然还会报错.太麻烦.所以最好不要返回ArrayList类型的数据.可以自己写个类用于传递数据.
      

  4.   

    public ArrayList myAL()
    修正为
    public List myAL()
      

  5.   

    to:mdxk(一笑家园)
    那一个public ArrayList myAL()改动啊?是服务器上面的吗?那不是把服务返回类型都变了啊!
      

  6.   

    初步搞定:(服务如何发布就不详细说了,网上很多)
    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/">
         &#x8FD9;&#x662F;&#x8C03;&#x7528;&#x670D;&#x52A1;&#x5668;&#x7684;&#x7C7B;&#xFF01;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">
        &#x8FD9;&#x662F;&#x8C03;&#x7528;&#x670D;&#x52A1;&#x5668;&#x7684;&#x7C7B;&#xFF01;web
       </bean>
      </multiRef>
     </soapenv:Body>
    </soapenv:Envelope>
      

  7.   

    正解:
    这一版没有把它写成服务\客户端的形式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();
    }
    }