[j2me]利用kSOAP让MIDP设备与WebService之间传递类对象[下]

简介:
 测试代码下载: http://files.cnblogs.com/zhengyun_ustc/WSCallerMIDlet.rar

[j2me]利用kSOAPMIDP设备与

WebService之间传递类对象

编写者

日期

关键词

郑昀@ultrapower

2005-8-14

J2me webservice soa ksoap serialization MIDP CLDC

 

第二小步,Web Service传递较为复杂的类

下面我们讲述如何MIDP设备和Web Service之间传递较为复杂的类,比如这个类中不但有String类型成员变量,还有Vector之类的复杂类型

kSoapFAQ上看,他们推荐使用KvmSerializable以及 ClassMap传递自定义类,但是我一直没有试验成功。

我还是按照能试验出来的办法讲述一下步骤吧:

大致思路就是,在服务器端将类实例按照一定规格(一个一个的成员变量写)序列化为byte[],将这个byte[]数组返回给kSOAPkSOAP收到之后反序列化,将byte[]一段一段地读入类实例。

Web Service服务器端的做法

先来定义要传递的wsTeam类:

类定义

public class wsTeam{

private String wsReturnCode;

private String wsPersonCount;

public StringVector  wsvPersonName;

public byte[] serialize();

public static wsTeam deserialize(byte[] data) ;

}

其中,StringVector类是另外一个自定义类,就是简单地把String[]封装了一下,便于操作。StringVector类定义在附录中可以找到。

服务器端主要是序列化,所以我们来讲讲wsTeambyte[] serialize()函数。

序列化

       public byte[] serialize() {

              ByteArrayOutputStream baos = new ByteArrayOutputStream();

              DataOutputStream dos = new DataOutputStream(baos);

 

              try

              {

                     dos.writeUTF(wsReturnCode);

                     dos.writeUTF(wsPersonCount);

                     wsvPersonName.writeObject(dos);

                     baos.close();

                     dos.close();

              }

              catch(Exception exc)

              {

                     exc.printStackTrace();

              }

 

              return baos.toByteArray();

       }

这样,类实例就可以把自己序列化为byte[]数组。

那么,Web Service可以这么提供:

服务器端

public class SimpleKSoapWS {

   

    public SimpleKSoapWS () {

    }

   

    public byte[]  foo2(String username, String password) {

        wsTeam obj= new wsTeam ();

           return obj.serialize();

}

}

到了MIDP设备上,要能够从byte[]恢复出wsTeam类实例才行。

 

StringVector的序列化方法writeObject也很简单,先写入字符串数组的大小,然后再将每一个元素写入,如下所示:

StringVector的序列化

public class StringVector

{…

public synchronized void writeObject(java.io.DataOutputStream s)

       throws java.io.IOException 

       { 

              //     Write out array length

              s.writeInt(count); 

              //     Write out all elements in the proper order.   

              for (int i=0; i<count; i++)

              {

                     s.writeUTF(data[i]);

              }

       }

}

 

MIDP设备的做法

和前面的MIDlet代码差不多,只不过要我们的ClassMap出场了

使用ClassMap

ClassMap classMap = new ClassMap();

(new MarshalBase64()).register(classMap);

HttpTransport tx = new HttpTransport(serviceUrl, methodName);

 

tx.setClassMap( classMap );

tx.debug = true;

MarshalBase64类定义在附录中可以找到。

这样,后面才能将接收到的SoapObject强制转换为byte[]

转换

Object Response = tx.call(request);

System.out.println( tx.responseDump );

byte[] by = (byte[])Response;

然后,再调用

反序列化

wsTeam wc = wsTeam.deserialize(by);

这样,在无线设备上就得到了wsTeam类实例了。

 

wsTeamdeserialize是这么定义的:

反序列化

public class StringVector

{…

       public static wsTeam deserialize(byte[] data) {

              ByteArrayInputStream bais = new ByteArrayInputStream(data);

              DataInputStream dis = new DataInputStream(bais);

              wsTeam wc = new wsTeam();

             

              try

              {

                     wc.wsReturnCode = dis.readUTF();

                     wc.wsPersonCount = dis.readUTF();

             

                     wc. wsvPersonName.readObject(dis);

      

                     bais.close();

                     dis.close();

              }

              catch(Exception exc)

             

                     exc.printStackTrace();

              }

 

              return wc;

       }

…}

StringVector的反序列化方法readObject也很简单,先读入字符串数组的大小,就自行新建一个同样大小的字符串数组,然后再将每一个元素写入这个数组,如下所示:

StringVector的反序列化

public class StringVector

{…

       public synchronized void readObject(java.io.DataInputStream s)

       throws java.io.IOException, ClassNotFoundException  

       {    

              //     Read in array length and allocate array  

              int arrayLength = s.readInt(); 

              data = new String[arrayLength]; 

              // 同步data的大小

              count = arrayLength;

              //     Read in all elements in the proper order. 

              for (int i=0; i<arrayLength; i++)

              {

                     data[i] = s.readUTF();

              }

       }…

}

 

通过上面的反序列化,我们就可以通过

for (int i=0; i<wc. wsvPersonName.size(); i++)

{

      System.out.println("" + i +"个人:" +

                 wc. wsvPersonName.getStringAt(i));

}

来打印MIDlet上收到的类对象中的StringVector成员变量了。

 

小结

利用相同的办法,您还可以在无线设备和Web Service之间,传递各种各样的类对象,类里面也包含了各种类型的成员变量。

 

编写者

日期

关键词

郑昀@ultrapower

2005-8-19

J2me webservice soa ksoap serialization MIDP CLDC

 

 

附录AStringVector

StringVector

/**

 * Vector主要用来保存各种类型的对象(包括相同类型和不同类型的对象)。

 但是在一些情况下使用会给程序带来性能上的影响。这主要是由Vector类的两个特点所决定的。

 第一,Vector提供了线程的安全保护功能。即使Vector类中的许多方法同步。

 但是如果你已经确认你的应用程序是单线程,这些方法的同步就完全不必要了。

 第二,在Vector查找存储的各种对象时,常常要花很多的时间进行类型的匹配。

 而当这些对象都是同一类型时,这些匹配就完全不必要了。

 因此,有必要设计一个单线程的,保存特定类型对象的类或集合来替代Vector

 */

package com.ultrapower.helper;

 

/**

 * @author VictorZheng

 *

 */

public class StringVector

{

       // 这儿的transient标示这个属性不需要自动序列化

       private transient String[] data;

       private int count;

       public int size()

       {

              return count;

       }

       public StringVector()

       {

           // default size is 10

              this(10);  

       }

       public StringVector(int initialSize)

       {

              data = new String[initialSize];

       }

       public void add(String str)

       {

              //     ignore null strings

              if(str == null) { return; }

              ensureCapacity(count + 1);

              data[count++] = str;

       }

 

       private void ensureCapacity(int minCapacity)

       {

              int oldCapacity = data.length;

              if (minCapacity > oldCapacity)

              {

                     String oldData[] = data;

                     int newCapacity = oldCapacity * 2;

                     data = new String[newCapacity];

                     System.arraycopy(oldData, 0, data, 0, count);

              }

       }

       public void remove(String str)

       {

              if(str == null)

              {

                     return; // ignore null str  

              }

              for(int i = 0; i < count; i++)

              {

                     //     check for a match

                     if(data[i].equals(str))

                     {

                            System.arraycopy(data,i+1,data,i,count-1); // copy data

                            //     allow previously valid array element be gc'd

                            data[--count] = null;

                            return;

                     }

              }

       }

      

       public final String getStringAt(int index)

       {

              if(index < 0)

              { return null; }

              else if(index > count)

              {

                     return null; // index is > # strings

              }

              else

              {

                     return data[index]; // index is good 

              }

       }

      

       public synchronized void writeObject(java.io.DataOutputStream s)

       throws java.io.IOException 

       { 

              //     Write out array length

              s.writeInt(count); 

              //     Write out all elements in the proper order.  

              for (int i=0; i<count; i++)

              {

                     s.writeUTF(data[i]);

              }

       }

      

       public synchronized void readObject(java.io.DataInputStream s)

       throws java.io.IOException, ClassNotFoundException  

       {    

              //     Read in array length and allocate array  

              int arrayLength = s.readInt(); 

              data = new String[arrayLength]; 

              // 同步data的大小

              count = arrayLength;

              //     Read in all elements in the proper order. 

              for (int i=0; i<arrayLength; i++)

              {

                     data[i] = s.readUTF();

              }

       }

}

 

附录BMarshalBase64

MarshalBase64

/**

 * @author VictorZheng

 *

 */

import java.io.IOException;

 

import org.kobjects.serialization.ElementType;

import org.ksoap.ClassMap;

import org.ksoap.Marshal;

import org.ksoap.Soap;

import org.ksoap.SoapParser;

import org.ksoap.SoapWriter;

 

 

/** Base64 (de)serializer */

 

 

public class MarshalBase64 implements Marshal {

 

    static byte [] BA_WORKAROUND = new byte [0];

    public static Class BYTE_ARRAY_CLASS = BA_WORKAROUND.getClass ();  

   

 

    public Object readInstance (SoapParser parser,

                            String namespace, String name,

                            ElementType expected) throws IOException {

 

       parser.parser.read (); // start tag

       Object result = Base64.decode

           (parser.parser.readText ());

       parser.parser.read (); // end tag

       return result;

    }

      

 

    public void writeInstance (SoapWriter writer,

                            Object obj) throws IOException {

 

       writer.writer.write (Base64.encode ((byte[]) obj));

    }

 

    public void register (ClassMap cm) {

       cm.addMapping

           (cm.xsd, "base64Binary",

            MarshalBase64.BYTE_ARRAY_CLASS, this);  

 

       cm.addMapping

           (Soap.ENC, "base64",

            MarshalBase64.BYTE_ARRAY_CLASS, this);

 

    }

}

目录
相关文章
|
7月前
|
存储 人工智能 自然语言处理
基于MCP的桥梁设计规范智能解析与校审系统构建实践
本文探讨了在桥梁设计领域应用AI技术的实践与思考,针对传统设计中规范查阅效率低、理解偏差大等问题,提出基于MCP协议构建智能解析与校审系统。系统通过PDF解析、知识图谱构建及自然语言处理等技术,实现规范条文的结构化存储和智能化应用,大幅提升设计效率与准确性。开发过程中克服了多模态文档解析、专业术语理解等挑战,并通过迭代优化持续改进性能。未来该系统有望扩展至更多工程领域,推动设计流程智能化升级。
197 8
|
11月前
|
人工智能 数据可视化 数据处理
【2025低代码前瞻】:平台赋能的无限可能
低代码平台正成为企业数字化转型的核心工具,2025年将通过可视化开发、核心引擎升级、模型驱动、数据处理增强、AI融合、插件生态丰富、开放架构和强化企业功能等趋势,大幅提升开发效率与灵活性。可视化开发实现全员参与,拖拽式组件、实时预览和多人协作等功能显著提高开发速度;核心引擎如SQL引擎、功能引擎等的智能化升级支持高效开发;模型驱动自动生成高质量代码,智能优化逻辑并确保跨平台兼容;数据处理能力增强,支持跨数据库操作与实时流处理;丰富的插件生态覆盖多行业需求;开放架构结合微服务与开源框架提升扩展性;低代码平台将在2025年为企业带来更高效率、更低成本和更强创新能力。
450 32
|
10月前
|
人工智能 数据挖掘
低代码 + AI 落地实践,让业务效率翻倍,解锁未来生产力!
2025年春节,DeepSeek引发AI讨论热潮,推动“数字化”到“数智化”的革新。低代码+AI组合降低了技术门槛,加速企业智能化升级。文中通过食品加工业原料溯源、家电售后管理、发票识别打印三个案例,展示其在效率提升和市场竞争力中的作用,并介绍钉钉宜搭举办的“低代码+AI”视频创作大赛,邀请读者参与探索更多实际应用。
1051 9
|
10月前
|
数据采集 JSON API
小红书笔记详情 API 接口(小红书 API 系列)
小红书作为热门生活方式平台,拥有海量用户生成内容。通过其笔记详情接口,开发者可获取指定笔记的完整内容、作者信息及互动数据(点赞、评论、收藏数等),助力内容分析与市场调研。接口采用HTTP GET请求,需提供笔记ID,响应数据为JSON格式。注意小红书有严格反爬虫机制,建议使用代理IP并控制请求频率。
1678 3
|
机器学习/深度学习 人工智能 文字识别
轻松识别文字,这款Python OCR库支持超过80种语言
轻松识别文字,这款Python OCR库支持超过80种语言
927 2
|
机器学习/深度学习 人工智能 监控
探索人工智能在医疗健康领域的创新应用
探索人工智能在医疗健康领域的创新应用
|
存储 JSON 安全
【权限设计系列】「认证授权专题」微服务架构的登陆认证问题
【权限设计系列】「认证授权专题」微服务架构的登陆认证问题
1204 0
【权限设计系列】「认证授权专题」微服务架构的登陆认证问题
|
Web App开发 开发框架 前端开发
Electron快速入手,拥有自己的第一个桌面应用
Electron 是一个跨平台的、基于 Web 前端技术的桌面 GUI 应用程序开发框架。 支持 Web 技术开发桌面应用,其本身是基于 C++ 开发的,GUI 核心来自于 Chrome,而 JavaScript 引擎使用 v8。 这使得我们使用前端技术就可以开发出属于自己的第一个桌面应用。
665 0
|
存储 运维 Java
基于SpringBoot的社区小型图书管理系统的设计与实现(一)
基于SpringBoot的社区小型图书管理系统的设计与实现
634 0