Terry.Li-彬

虚其心,可解天下之问;专其心,可治天下之学;静其心,可悟天下之理;恒其心,可成天下之业。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  143 随笔 :: 344 文章 :: 130 评论 :: 0 Trackbacks
我的代码如下:
这是发布到服务器上面的代码:
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>
20 
发表于:2007-01-10 17:29:401楼 得分:0
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>

发表于:2007-01-19 16:48:182楼 得分:0
正解:
这一版没有把它写成服务\客户端的形式

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();
}
}
posted on 2007-11-24 14:41 礼物 阅读(3440) 评论(0)  编辑  收藏 所属分类: webservice