您的位置:首页 > 其它

企业管理软件在J2ME无线平台的应用

2009-10-03 09:58 309 查看
企业管理软件在J2ME无线平台中的应用

级别: 初级
刘金柱 (suntoday@eyou.com), 高级软件工程师, 金蝶软件金融事业部
2002 年 9 月 10 日
本文主要叙述传统计算机管理软件与支持JAVA虚拟机的无线设备进行数据库交互的体系结构。随着无线开发平台软、硬件环境的成熟和完善,PC软件系统与无线设备的数据交换将成为普遍流行的整体解决方案,给传统计算机管理软件带来一次新技术的革命。
延伸的无线设备用户
在当今,计算机管理系统广泛服务于全球各地的企业、组织中,为企业创造着巨大价值。系统终端用户已经被覆盖到企业Intranet或广域的Internet中,使用户更加容易简单的获得系统服务。这样就满足用户对获得系统服务的需求了吗?企业的采购员可能想在路途中知道当前仓库中的动态存货量,销售人员在和客户谈判时可能想立刻获知当前在库产品价格和数量以争取到一笔大的销售定单,你无法预知你的系统用户在什么时刻需要获得计算机服务,传统的管理软件约束了用户更多正常行为。无线技术应用延伸了客户端用户对空间位置的需求,使这些企业需求变为现实。

回页首
在无线设备编程中的J2ME体系
无线接入设备的可定制化编程能力被第三代 (3G) 和GRPS宽带无线网络所推进,从而可以在无线网络中传输视频信号和高质量的音频信号,而在这些基础网络硬件的推进下,无线设备已不象过去那样提供制造商所固有的编码程序,各种无线设备开发平台逐步形成,并成为业界生产和制造标准,这些设备将支持动态程序下载、自动安装、用户触发执行等功能。Java语言最初是用户消费类型产品的编程,非常适合无线设备编程的特点,例如支持广泛的网络协议、安全性、平台交叉的兼容性、纯面向对象的开发过程等。
Java技术经过多年的发展,已经是一种非常成熟的编程语言,但是使用传统的Java虚拟机和类库并不能够运行在这些资源相当受限的设备上(例如普通手机内存只支持几十到几百字节)。1999年由JCP(Java Community Process,JCP)公布了互联受限设备配置(Connected,Limited Device Configuration,CLDC),和移动设备描述(Mobile Information Device Profile,MIDP)。CLDC为大量不同制造商、不同类型的互联资源受限设备的Java平台提供了"最低公共标准"的核心类库和Java语言、虚拟机等特征,并将定义的范围缩到最小,已能够适应广泛的无线设备,而MIDP则基于CLDC定义的平台之上,针对移动设备而扩展的一些API。这些规范和通用框架被称为Java 2平台微缩版(Java 2 Platform,Micro Edition,J2ME)

但是J2ME并不能定义所有设备制造商、其他原始设备制造商所拥有的特性,列如Motorola Java手机(下面的无线设备就以KJava手机为例)可能与PalmOS提供不同的手机特性,为此各厂商提供自己的OEM类库来访问特定的功能。
J2ME提供了开发无线应用的标准类库,作为这篇文章最关心的部分,J2ME提供了通用的支持输入/输出的互联框架,使用这个框架允许无线设备具有网络通讯输入/输出的可编程能力,如下图所示:

调用格式:
Connector.open("<protocol>":"<address>":"<parametes>");
所有的连接都通过调用javax.microedition.io.Connector类中的方法open来创建,通过这个连接类,我们可以方便的实现无线设备与PC服务器进行TCP/IP的socket的通讯:
StreamConnection conn=(StreamConnection)
Connector.open("socket://www.cn-java.com:8080");
InputStream in = conn.openInputStream();
OutputStream out= conn.openOutputStream();
在企业实际案例中,应用更广泛的是透过防火墙来访问企业数据库的Http方式,我们也可以简单的使用下面的方式来实现无线设备与PC服务器进行TCP/IP的http通讯:
HttpConnection conn=(HttpConnection)
Connector.open("http://www.cn-java.com/index.php");
InputStream in=conn.openInputStream();
OutputStream out= conn.openOutputStream();
在CLDC定义的框架中,所有Connection都继承了实现了Connection接口,如下图所示:

在MIDP提供了一套标准的用户界控件面库和屏幕模型,屏幕模型是MIDP界面的核心概念,屏幕模型可以帮助开发者根据不同需求组装成不同的屏幕,有两种屏幕类型:Canvas和Screen。Canvas可以允许开发者在屏幕上画置图形、响应用户输入的低级对象,功能灵活,但编程难度较大,而Screen则是一个封装了完整用户界面的高级对象(Alert、List、TextBox、Form)。一个完整的应用可以由两种类型的屏幕交互组成。
如果屏幕类被扩展了Form类型,则可以在Form中包含下面的Item类:
StringItem -显示字符串
ImageItem -显示图象
TextField -受限的文本输入
DateField -显示日期时间
Gauge -显示图形化的值
ChoiceGroup - 单选和多选框
一般情况一个简单的界面应用可以由Screen类型的屏幕完成,如果应用界面比较复杂,则需要使用Canvas方式将画面一一画出,并自己写程序负责事件的响应机制。

回页首
在原有旧系统上实现无线设备的数据交换
应用无线设备让企业管理系统更加高效和灵活,但是更多的计算机管理软件系统在当初设计时可能并未考虑过实现无线设备应用,在企业的软件投资过程中,投资应当受到合理的保护,给遗留系统添加无线设备访问能力成为一个值得研究的课题。
1.可行性分析
传统企业管理系统一般为C/S、B/S或混合而成,支持无线设备的首要条件是网络环境。KJava手机或其他Java无线设备可以通过Http或Socket协议访问Internet资源,因此,企业数据库必须能够通过互联网进行访问,如果企业管理系统由于硬件环境不能接入Internet,则与普通无线设备进行交互的可能性不大。在物理环境下,企业数据库必须能够与外界internet进行数据交换。
无线设备作为一种资源受限设备,相较PC程序而言只能完成比较简单的界面交互,内存和CPU处理能力的限制使不进行大规模数据计算和图形处理,屏幕和键盘输入设备也不是很方便,开发成本也较高。因此,需要分析哪些业务数据是有必要与无线设备进行数据通信。由于各种Kjava无线设备厂商生产的设备在除了支持J2ME标准外,一般都会增加一些OEM特性,以能够访问其设备特性,因此需要考虑到支持市面上哪类家族的无线设备,是Nokia系列还是Moto系列,也可以为不同家族的手机开发出不同J2ME程序(在UI控制方面有自己的开发包)。
2.制定客户端与服务器端通讯接口标准
无线设备中的Java虚拟机只提供了设备的可编程能力,数据的IO传输等,因此,在开发服务器端系统和客户端(无线设备)系统前需要制订出一套完善的通讯接口。要制订这一个接口首先应该清楚的是当两者通讯时,我们一般会使用流的方式,既把一个请求数据或响应数据编码成一个长的流,流内包含的数据使用约定的分割符号进行界定,例如发送登录命令的请求流的编码顺序可能是这样的: login jackliu 123456 解释:login 表示登录请求,一个空格后表示跟随一个用户名,另一个空格跟随口令,但也可能是这样的 01 _name[jackliu]name_ ps[123456]ps_ 解释:01表示登录请求,_name[和]name_之间表示用户姓名,_ps[和]ps_之间表示登录口令,可以看出流的编码方式是多样的,只要能够让服务器端和客户端识别,遵循简单、通用的原则制定即可(也可以使用xml语言来描述,但是我觉得目前手机内存和CPU计算能力较弱,适合J2ME的xml解析器也不多)。
3.开发服务器端响应系统
无线设备不支持直接访问数据库的能力,而企业管理系统多数都由大型数据库支持,因此我们需要编写一套服务器端程序来接受无线设备的请求指令,通过解析请求、执行逻辑、响应结果的方式把数据再传回给无线设备。旧的原有系统很可能采用非Java语言开发,如果服务器端系统使用Java语言开发可能对原软件供应商存在技术障碍,同时原有系统逻辑不容易与Java集成。在这种情况下,服务器端程序就不一定使用Java编写,由于是使用Http或Socket通讯,使服务器端程序可以由任何支持Http协议或socket协议的程序语言编写。

4.开发无线设备客户端
使用J2ME提供的API和MIDP类库开发无线设备的客户端系统,由于MIDP提供的标准界面类库往往不能完全满足各类资源受限设备的特性,可能会是使用到具体无线设备家族的OEM类,类如专门为Motorola开发时的LWT类库,一般来说使用了这些类库会影响KJAVA程序的可移植性,但由于OEM类是基于CLDC规范之上的类库,所以可以很容易的更换成其他厂商的OEM包以能够运行在其他的Java无线设备中。

回页首
对一个遗留系统进行改造的例子
通过一个例子来说明我们应该如何改造一个遗留的旧系统,以让他支持无线设备。我们来描述一下这个旧系统的基本功能和用户的新需求:
A证券公司,几年前,开发了一套基于C/S结构的证券系统,数据库被共享在Internet上,公司可以通过证券系统查询各种股价信息和交易数量。现在,公司希望能够功过手机等类似无线设备时时能够查询到这些股票信息,并且要求保留原有的系统平台功能。
我们分析这套系统基于C/S 结构,无法直接和手机使用http通信,需要单独为此开发一套基于http协议的后台服务程序,让手机通过http来调用这个服务程序,框架如下图:

这里仅实现一个按股票代码查询股价信息的功能来说明这个开发结构。
1.制订通讯协议标准
手机发出请求某支股票价格询问命令协议格式:
_command[007]command_ _uid[]uid_ _stockNo[]stockNo_
服务端响应协议格式:
_command[008]command_ _stockTitle []stockTitle_ _stocktPrice[]stockPrice _
2.开发服务端程序
假设服务器端我们使用Servlet开发,为了能够接收到请求,我们打算设计一个MyWirlessServlet来实现,基本代码如下:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.sql.*;
public class MyWirlessServlet extends HttpServlet{
public void init() throws ServletException{}
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException{
//不在doGet种操作,手机与其通讯时要采用doPost方式,所以我们要在doPost写处理
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException{
DataInputStream in = new DataInputStream
(new BufferedInputStream(request.getInputStream()));
DataOutputStream out = new DataOutputStream
(new BufferedOutputStream(response.getOutputStream()));
String reqData=in.readLine(); //获取请求命令行
….//此处根据reqData来访问数据库,把结果编码成响应格式
String repData="_command[008]command_ _stockTitle
[A股票]stockTitle_ _stockPrice[12.85]stockPrice _";
out.writeUTF(repData);//用UTF8格式编码发送给手机
out.flush();
out.close();
}
3.开发手机端程序
这段程序使用了标准的J2ME开发包
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
public class HttpDemo extends MIDlet implements CommandListener{
private Form form;
private Command exitCommand=new Command("Exit",Command.EXIT,1);
private Command okCommand =new Command("OK",Command.OK,2);
private Display display;
public HttpDemo() {
display=Display.getDisplay(this);
}
protected void pauseApp() {
form=null;
display.setCurrent(null);
}
protected void startApp() {
form=new Form("股价查询:");
form.addCommand(exitCommand);
form.addCommand(okCommand);
form.setCommandListener(this);
display.setCurrent(form);
StringBuffer sb=new StringBuffer();
String url="http://www.cn-java.com:8080/ MyWirlessServlet ";
HttpConnection conn =null;
DataInputStream in=null;
OutputStream out=null;
try{
conn =(HttpConnection)Connector.open(url);
conn.setRequestMethod( HttpConnection.POST ); //设置连接为Post方式
conn.setRequestProperty( "User-Agent", "Profile/MIDP-1.0 Configuration/CLDC-1.0" );
conn.setRequestProperty( "Content-Language", "en-US" );
out= conn.openDataOutputStream();
//发送请求给出股票代号是999的股票价格信息
out.write("_command[007]command_ _uid[jackliu]uid_ _stockNo[999]stockNo_";
out.flush();
out.close();
in= conn.openDataInputStream();
//读返回得结果,这里我们没有做解析处理
sb.append(is.readUTF());
}catch (Exception e){
sb.append(e.toString());
}finally{
try{
if(in!=null)in.close();
if(out!=null)out.close();
if(conn!=null)conn.close();
}catch(java.io.IOException ioe){}
}
//将股票价格信息显示到手机屏幕上
form.append(sb.toString());
}
protected void destroyApp(boolean parm1) {}
public void commandAction(Command c,Displayable s){
if(c==exitCommand){
destroyApp(false);
notifyDestroyed();
}
}
}
模拟屏幕测试如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: