- 1 -
基于 J2ME及 XML的移动设备数据交换1
吴小娟,杨春金
武汉理工大学信息工程学院,湖北武汉 (430063)
摘 要:本文研究了资源有限的小型移动设备与服务器数据库间的数据交换机制,采用功能
强大丰富的 J2ME 作为移动应用开发平台,以广泛应用于数据交换的 XML 格式为数据载
体,完成小型移动设备与主服务器数据库间的数据交换,并将之在京珠高速公路信息管理系
统外场采集中实现。
关键词:移动数据交换;J2ME;XML格式;kXML2;中文乱码
1. 引言
随着近年来无线技术的发展和无线通讯设备的不断普及,基于手机、PDA 等小型消费
类和嵌入式设备的无线移动应用越来越广泛。虽然存在着各种类型的手机平台,但在可编程
手机中,基于 Java 的手机是最为通行的,事实上,Java 已经为差不多所有的手机制造商所
接受,成为手机应用与服务的标准[1]。Java 语言的跨平台性,使得第 3 方软件开发商可以很
容易地开发应用程序,方便地将应用程序安装移植到移动设备上,并且还能支持应用程序的
动态下载和升级。Java 2 平台 Micro 版(Java 2 Platform Micro Edition, J2ME) 是专门设计为
供内存量小、处理能力较低的移动设备作为 Java 开发平台使用的。
本文研究在 J2ME 平台上,实现移动设备与主服务器数据库间的复杂数据结构的交换。
基于移动设备特殊的数据存储机制及资源有限的特点,以 XML 格式为数据交换载体,在京
珠高速公路信息管理系统外场采集中实现,并分析了其中可能出现的中文乱码的解决方案。
2. J2ME 体系结构与数据存储机制
J2ME 的体系结构中包括建立在硬件、操作系统之上的 Configuration,Profile 及建立在
Profile 之上的 Java 应用程序。Configuration 是底层的配置,规定了 Java 虚拟机(JVM)的
功能以及该配置所用的基本类库(Library),功能比较少,分为适用于高端信息家电的 CDC
(Connected Device Configuration,面向连接的设备配置)和适用于低端信息家电的 CLDC
(Connected, Limited Device Configuration,面向连接受限的设备配置)两类。Profile 架构于
Configuration 之上,负责建立高级扩展类库,功能丰富,与 Configuration 一起为应用程序提
供基本环境。对移动设备而言,主要的Profile规格是MIDP(Mobile Information Device Profile,
移动信息设备简表)。MIDP 规范包括应用程序生命周期,各种用户界面组件,支持存储和
网络连接等。MIDP 应用程序称为 MIDlet。
MIDP 规范中为 MIDlet 应用提供了一个访问和处理 MIDP 设备上的持久数据存储机制:
“记录管理系统”(Record Management System,RMS)。RMS 是面向记录的数据库模型,数
据保存在记录库(Record Store)中,库中每一条数据也被称为记录。如果把一个记录库当
成数据库表,那么该表中只有两个字段:一个整数类型的记录 ID 和一个字节数组表示的记
录数据[2],如表 1 所示。
1本科题得到湖北京珠高速公路信息管理系统,湖北省交通厅立项课题的资助。
- 2 -
表 1 记录库结构
记录 ID(int) 记录数据(byte[])
然而,服务器端数据库如 SQL Server 的表绝大多数是多字段的,如图 1 所示。
图 1 SQL Server 数据库的表
因此, RMS 与服务器端数据库间不能直接进行复杂数据结构的交换,必须经过一定的
数据处理。
3. XML 特性及解析
XML(Extensible Markup Language,可扩展标记语言)是 Internet 环境中跨平台的、依
赖于内容的技术,是当前处理结构化文档信息的有力工具,适用于描述任何结构化或者半结
构化的数据,适合作为各种数据存储与共享的通用平台,提供了一种结构化的简单方法来存
储和通信数据,这在分布式环境中十分有用。由于 XML 具有良好的格式与逻辑结构,XML
应用软件可采用简单的原则来区分文档中的数据与 XML 标记[3]。XML 已成为了网络通信
中数据交换的标准技术,广泛应用于数据交换领域,具有优秀的跨平台特性。
因此,在传输移动设备 RMS 与服务器端数据库间复杂数据结构时,可以将数据库表表
示成 XML 标准格式,将表中每条记录作为 XML 根元素的一个子元素,每个字段作为该对
应记录的子元素,如下所示。
< Datainfo >
< Data ID = 1 >
< DY10 > 182 < /DY10 >
< XM01 > 0 < /XM01 >
< XM02 > 168 < /XM02 >
< XM04 > 行车道 < /XM04 >
……
< /Data >
< Data ID = 2 >
- 3 -
< DY10 > 183< /DY10 >
< XM01 > 0 < /XM01 >
< XM02 > 162 < /XM02 >
< XM04 > 停车带 < /XM04 >
……
< /Data >
……
< /Datainfo >
XML 根元素的每个子元素树表示成字符串后在 RMS 中存成字节数组,这样即完成了数
据结构的转换。
相应地,数据转换成 XML 标准格式后需有 XML 解析器才可以正常通信。XML 有两种
解析方式:DOM 和 SAX。DOM 方式让解析器读取全部文档再分析,在内存中建立一棵具
有层次结构的树,即可遍历、修改文档元素;SAX 方式则是逐行读取文档,然后调用用户
提供的函数,这些函数能够通知用户关心的事件。这种按事件驱动的方式称为“push”模型。
此外,还有一种实现了前向分析机制的“pull”模型,可以向解析器请求下一个元素或跳过不
感兴趣的元素[1]。鉴于移动设备内存有限的特点,适用于移动设备的 XML 分析程序有以下
几种:kXML,MinXML,NanoXML,TinyXML。相比而言,kXML 支持 MIDP,只占很小
存储空间,基于“pull”的分析,作为增量解析器在解析数据量较大时效率较高。故在移动设
备端采用 kXML2 解析 XML。
4. 系统设计与实现
总体设计
京珠高速公路信息管理外场采集系统包括客户端(即移动设备,如手机、PDA 等)和服
务器端两部分。服务器端应用 JSP、Servlet 等技术完成数据库操作、数据管理以及信息管理
系统其它模块的实现;客户端完成京珠高速外场数据采集,包括公路合同段及病害定义数据
的更新和病害数据的录入、管理及上传。总体设计框架如图 2 所示。
图 2 系统总体设计框架
数据传输机制
所有 MIDP 设备都必须提供的通信协议是简单的 HTTP。该系统使用一个专用的消息编
码方式,调用 MIDlet 与服务器进行通信,传送 XML 数据。客户端使用输出字节流
OutputStream 向服务器上传病害数据,部分代码如下:
- 4 -
HttpConnection http = null;
OutputStream os = null;
String url = + "/TransXMLServer/ReceiveXML";
// 使用HTTP协议与服务器建立连接,为连接地址
http = (HttpConnection) (url);
// 发送请求方法
();
("User-Agent", "Profile/ Configuration/");
os = (); // 打开一个输出流
(("UTF-8")); // 发送病害数据到服务器
();
在客户端更新合同段及病害定义数据时,需先向服务器发送更新类型信息,采用直接
URL 后加入变量的方法。
String url = +"/TransXMLServer/SendXML?intType="
+ ; // 为更新类型信息
客户端使用 InputStream 接收服务器发送的定义数据,部分代码如下:
InputStream is = null;
if (() == _OK)
{ ……
is = ();
…… }
J2ME 上 XML 数据转换与解析
J2ME 上采用第三方解析器 kXML 解析 XML 数据格式。将数据库表的每条记录解析出
来后存成一个 JavaBean 对象并添加到一个 Vector 中,再一一转成字节数组保存到 RMS 中。
首先需要将 添加到 J2ME 工程的构建路径中,在 XML 解析类
中导入:
import ;
import ;
import ;
在 中读取从服务器接收的输入字节流,解析 XML 数据格式,部分
源代码如下:
private InputStream is;
Vector v=new Vector();
public ReadWithKXML(InputStream is){
= is; } // 在解析类的构造方法中读进InputStream对象
public Vector run() {
KXmlParser parser = new KXmlParser();
(is, "UTF-8");
int eventType = 0;
// 定义一个事件采用回调的方式,直到读取xml完毕
eventType = ();
String strTagName = null;
while (eventType != _DOCUMENT)
- 5 -
{ if(eventType == _DOCUMENT)
{ ……
}else if(eventType == _TAG)
{ strTagName = (); // 得到当前Tag名字
// 数据处理,读取子元素,设置标志位intflag,用于标志更新信息类型
if(("DY10")){ intflag = 110;}
else if (("DY00")){ intflag = 19;}
……
}else if(eventType == _TAG)
{ ……
}else if(eventType == )
{ String strNewItem=(); // 获取文本
// 根据标志位intflag将currentbean添加到向量v的末尾
if(110==intflag){
XMDY currentbean=new XMDY();
=(strNewItem);
(currentbean);
intType = 1;
}else{……}
if (22==intflag) { ……
}else {……}
intflag=0; // 标志位复位
}eventType = (); // 遍历下一个事件,返回一个事件的类型
}
if(eventType == _DOCUMENT)
{……}
return v; } // 返回存有解析后JavaBean对象的向量v
在主程序中将向量v中的JavaBean对象一一并保存到RMS中:
for (int i = 0; i < (); i++)
{ XMDY currentbean = (XMDY) (i);
=();
byte b[] = (); // 把JavaBean对象转为字节数组
(b, 0, );
}
服务器端的实现
服务器端主要由两部分组成,一部分接收客户端发来的更新类型信息,据此查询数据库
相关表,并将表数据转换成标准的XML格式再发送给客户端;另一部分接收客户端上传的
病害数据并更新数据库相关表。现主要分析前一部分,主要实现由实现,部
分源代码如下:
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{ …… // 获取更新类型信息
intXMLdataType = (("intType"));
- 6 -
……
conn = (); // 连接数据库
…… // 查询数据库表并获得相关结果集rs
strXMLdata="<DataInfo>"; // 数据库表数据转成XML格式后存放有字符串strXMLdata中
while (())
{ int DY10=(1); String DY00=(2); ……
strXMLdata = strXMLdata + "<XMDYData ID='" + i + "'>"+ "<DY10>" + DY10 +
"</DY10>"+ "<DY00>" + DY00 + "</DY00>";
……
i++;}
("text/html;charset=UTF-8");
PrintWriter out = ();
(strXMLdata); // 向客户端发送定义更新数据
();
}
其它技术问题的解决
此外,在移动设备上传输或存储数据信息时常会遇到中文乱码问题。原因为指定的编码
格式与数据实际的编码格式不符,造成数据被编码成指定的替代符号或被解释成与源字符完
全不同的字符或无法在字符集中找到与其对应的编码。避免乱码的关键是保证中文编解码使
用同样的格式。J2ME 设备基本上都支持 UTF-8 的编码法,故在系统中传输及存储数据时,
确保数据都采用 UTF-8 编解码。具体实现如下:
服务器端发送数据时:
("text/html;charset=UTF-8");
PrintWriter out = ();
(strXMLdata); // strXMLdata 为包含中文字符的 XML 数据
客户端接收数据并从 XML 格式数据中解析出中文:kXML2 提供以下方法指定编码格式
(InputStream is, String _enc) //第二个参数指定为 UTF-8
客户端用 UTF-8 编码向记录库中写入中文:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
(DY00); …… // 向数据输出流写入包含中文字符的数据
byte b[]= ();
(b, 0, );
客户端从记录库中读出 UTF8 编码的中文:
byte b[]=(); // 获取记录库下一条记录
ByteArrayInputStream bis = new ByteArrayInputStream(b[]);
DataInputStream dis = new DataInputStream(bis);
String XM13 = (); // 解码出包含中文字符的数据
5. 总结
随着网络与硬件功能的增强以及基于 J2ME 的移动设备软件系统的发展,移动设备上复
杂数据结构的应用会越来越广泛。本文通过在京珠高速公路信息管理系统外场采集中的实
- 7 -
现,研究了基于 J2ME 平台和 XML 标准格式的移动设备与主服务器数据库间复杂数据结构
的交换机制,并分析了其中可能出现的中文乱码问题的解决方案,对于类似软件系统的开发
具有一定的参考价值。
参考文献
[1] 唐大仕.《用 Java/C#开发手机程序及移动应用》[M].北京:电子工业出版社,2004,4.
[2] 陈旭东,徐保民,张宏勋.《J2ME 应用教程》[M].北京:清华大学出版社,北京交通大学出版社,2007,1.
[3] 高怡新,《XML 基础教程》[M].北京:人民邮电出版社,2006,11.
[4] Kim Topley 著.《J2ME 技术手册》[M].张伶,林琪译.北京:中国电力出版社,2004,2.
[5] 孙鑫.《Java Web 开发详解——XML+XSLT+Servlet+JSP》[M].北京:电子工业出版社,2006,8.
Data Exchanging on Mobile Equipment based on J2ME and
XML
Wu Xiaojuan, Yang Chunjing
Wuhan University of Technology Information Engineering College, Wuhan, Hubei (430063)
Abstract
This paper researches the mechanism of data exchanging between mobile equipments with limited
recourses and databases on server end. And it accomplishes the data exchanging in Jingzhu Thruway
Management Information Outfield Data Acquisition System, with J2ME which has powerful functions
as the mobile applications developing environment and the format of XML which is used in data
exchanging widely as the data carrier.
Keywords: Mobile data exchanging; J2ME; Format of XML; kXML2; Garbled characters