wap!delphi能做到!——
应用于移动电话的WML(Wireless Markup Language)开发
河南省
本文作者:Jani J vinen
翻译整理:崔凯
众所周知,delphi有创建HTML文件的能力。然而,你知道吗?delphi也能用来创建一些新的WAP(Wireless Application Protocol) 设备所需要的WML文件。
这篇文章中,你将学习到如何创建一个快速的,使用一个wap电话或者是一个模拟系统的定制查询系统。现在来让我们来超越一下我们自己,来,让我们从头开始。
WAP是最新的可支持WAP的第三代移动电话所使用的协议。很多人都认为:WAP将把internet带入移动电话中去,这不完全正确;毕竟,现在我们还不能使用WAP来实现网上冲浪。WAP所能做到的无非是让你检索到和显示为WAP电话而专门开发的特殊文件。这些文件是使用WML语言来编制的。
WML语言和html语言类似,尽管还有很多格式化操作例如:嵌套表,层,颜色,还有不一样的打印字体等,这些还不能应用到WML中。但WML确实允许开发人员定义简单的文本格式,如:图像,链接,和文本输入的字段。它之所以只有这么简单应用,关键原因在硬件上。因为现在的移动电话还不能先是如此丰富的格式化操作。现在的移动电话只是使用很少的像素显示(大约是200*200),并且刚开始只能使大约4种灰色调,现在可以显示彩色了。这时,就需要一个新的标记语言来做这种电话的软件应用,因为,当前的HTML文件不能适合这样的屏幕了。这就是WML.协议。
WAP设备是通过标准的URL( Uniform Resource Locator ,在Internet的WWW服务程序上用于指定信息位置的表示方法)来访问的。当WAP设备的使用者在他的WAP移动电话或者是其他设备上输入URL的时候,这台设备开始跟一个为它服务的WAP网关通过无线电波联系。
一个这样的网关通常会是由移动通讯设备操作人员的一台主机来代替,例如:MCIWorldCom或者是Sprint(截稿时,这两家公司的合并正悬而未决,但股东们已经基本同意了)。这台网关计算机除了接收移动电话的请求,并通过HTTP协议把它转到通常的INTERNET上去。在这里,那些设备提供WEB服务,它响应这些请求,并且把相关的WML数据返回到这台网关计算机上。这时,这个网关计算机在把相应的WML文件返回到发出请求的移动电话,最终在WAP移动电话的使用者面前显示这些文件。这就是整个通讯的全过程。
注:MCIWorldCom和Sprint都是美国著名的通讯公司,而在中国,是由中国移动通讯公司扮演该角色。
由于在INTERNET上使用HTTP协议来访问WML文件,所以WAP技术不需要设备提供商提供特殊的软件和硬件设备。一般的WEB服务,例如Apache和IIS(Microsoft Internet Information Server),都可以配置成适当的WML文件。而且,一个单一的WEB服务可以同时服务HTML和WML页面,正如WEB服务可以服务于各种不同类型的文件,例如:gif,jpeg,zip等。然而,应当制定一个单独的(虚拟的)WEB服务来为WAP服务,因为这样能使的用户更容易的记着那些URL.语言
---- WML是一种使用XML语法的语言。这意味着WML可以使用任何文本编辑器来写,甚至可以使用Notepad。而且,WML类似于HTML,许多WML标识符,例如:< b >, < i >, < big >, 和< a >都和在HTML中有着几乎完全相同的意义。以下代码是一个WML的例子:
< ?xml version="1.0"? >
< !DOCTYPE wml PUBLIC "-// WAPFORUM// DTD WML 1.1
// EN" "http://www.wapforum.org/DTD/wml_1.1.xml" >
< wml >
< card id="welcome" title="Welcome to" newcontext="true"
ontimer="#login" >
< timer value="30"/ >
< p align="center" >
< big >MA's On-line< /big >< br/ >
< em >Order Query System< /em >
< /p >
< /card >
< /wml >
---- 以上是一个使用WML 1.1版本编程的例子
---- 有一点WML和HTML不一样的地方是:在WML中一个文件不是像在HTML中叫做文件,而是叫做卡片组(deck),一个卡片组是有一个或者更多的卡片(card)组。WAP手机屏幕上一次只能显示一张卡片,而且它仅仅能显示几行文本。
---- 现在的WAP手机一次只能处理小于1K字节的WML代码。所以,用WML写出来的代码必须非常小。并且,由于在WAP手机屏幕上显示的文本数量很有限,所以每一个WML代码必须很短。
---- 如果一个WAP卡片上的数据不适合屏幕大小的话,用户被迫滚动滚动条才能看清楚屏幕上的内容。现在最好的WAP手机不需要扩展的滚动条,与之相适应的是上面提供的都是小块的信息。用户现在可以在不同的窗口中通过前后翻屏的的操作浏览网页。
---- 浏览时用户可以使用一般的超文本链接,就像在WINDOWS中称之为任务条的东西,它可以使用一些特殊的用WML标识符编写的< do > 命令。
---- 例如,标识符< do type='accept' > < prev/ > < /do > 将允许用户在WAP设备中向后浏览网页。
---- 为了使用更为丰富的命令,而不仅仅是向前或者是向后浏览网页,WML可以被扩展成一种脚本语言,成为WMLScirpt. WMLScript就类似于在html世界中的JavaScirpt脚本。但是当然了,它的功能还很有限,但他仍然能够满足用户的输入,进行简单的计算,或者设置WAP浏览状态等的要求。开发工具为帮助用户实现WAP的解决方案,Nokia已经开发了一个基于java的wap 开发工具。它可以用来创建,测试,或者是调试wap设备。(请看下图)
---- 一个wap开发工具模拟一个真正的wap手机和微型浏览器。这个开发工具允许从磁盘或者是interner上载入任何类型的的wml 文件。当载入后,这个wap仿真系统处理该文件并将它显示在屏幕上。这时,开发人员可以使用移动电话的按钮来输入文本,选择选项和进行wap设备的定位。
---- 导航条可以通过使用书签来实现,这是这个开发工具本来就支持的。事实上,书签只是使得开发者的工作变得简单化的一个简单例子。例如:这个开发工具允许实时监视使用WML和WMLScirpt语言创建的各个变量。正如同在delphi中的'watch'窗口。虽然这个开发工具提供的功能非常有限,毫无疑问的,这个实时查看变量的功能使得开发者调试WML代码更加容易。
---- 由于这个开发工具允许开发者在标准HTTP协议下载入任何类型的文件,所以说,这个仿真系统是一个相当棒的测试运行在一台WEB服务器上的交互式系统的工具。当然了,这些页面都可以动态创建。DELPHI5通过内嵌的WebBroker技术来对构建web解决方案提供了很好的支持。通常, webbroker技术是用来创建动态的html解决方案,现在有很多流行的web服务器都采用。然而,由于它的灵活性,webbroker技术也可以用来创建WML。
---- DELPHI的解决方案
---- 又一个可提供下载的例程:是一个ISAPI的DLL程序。它可以在IIS3.0或者是更新的版本上运行,详细介绍这个ISAPI 的DLLS的文件超出了本文的范围,但是你可以在INTERNET上找到关于ISAPI的详细信息。其中最好的源代码是在 http://www.delphizine.com/include/Click_Redir.asp?Url=http://msdn.microsoft.com/. 上的Microsoft Developer Network (MSDN) 。需要查看调试ISAPI的DLLS的信息,请访问: http://www.delphizine.com/features/ 2000/04/di200004jj_f/di200004jj_f.asp#SidebarOne 在其中查看工具条"Debugging ISAPI DLLs."
---- ISAPI DLLS的缺省返回的是一般的HTML代码,它可以人工创建,也可以在DELPHI中的页面处理控件使用。当然了,最大的优点是DELPHI允许它很容易的连接到数据库,它可以查询到插入到HTML代码中的数据。我们的例程确实是这样实现的,它查询一个数据库,创建一个包含信息的WML,并且将查询的结果返回给用户。直接的说,例程使用的是在DELPHI中的DBDEMOS数据库别名。
---- 这个DBDEMOS数据库允许访问一个关于海上冒险的潜水设备转售的虚拟用户和订单数据库。这个例程允许WAP手机用户来浏览一个实时的给出的用户的订单信息。这个例程的名字叫:"海上冒险订单在线查询系统",或者简称为MAOOQS(关于下载的详细信息,请看本文结尾的详细细节) 。
---- 登录到海上冒险程序
---- 当你想使用MAOOQS的时候,在你的WAP手机上(或者是在WAP的开发工具中)输入http://myserver/login.wml,这时WML浏览器交要的显示一个"Welcome to" 屏幕,然后会出现一个登录屏幕,"Welcome to" 和登录卡的WML源代码如下所示:
< card id="welcome" title="Welcome to" newcontext="true"
ontimer="#login" >
< timer value="30"/ >
< p align="center" >
< big >MA's On-line< /big >< br/ >
< em >Order Query System< /em >
< /p >
< /card >
< card id="login" title="Login" newcontext="true" >
< p >
< em >Enter your ID:< /em >< br/ >
< input name="custid" value="1221" maxlength="4"
format="*N" emptyok="false"/ >
< em >Enter your password:< /em >< br/ >
< input name="password" value="HI" maxlength="10"
format="*M" emptyok="true"/ >
< br/ >
< do type="accept" label="Login" >
< go method="post" href="/scripts/ma_ooqs.dll/login" >
< postfield name="custid" value="$(custid)"/ >
< postfield name="password" value="$(password)"/ >
< /go >
< /do >
< /p >
< /card >
---- 登录屏幕包括两个输入字段,一个是用户的ID ,另外一个是密码。这两个字段是使用WML的< INPUT >标识符来创建的,用户输入的各种各样的名字是由NAME属性定义的。
---- < DO >标识符定义了一个< go >的作用,它指向例程的ISAPI 的DLLS(确省的路径是/scripts/ma_ooqs.dll)。< go >使用标准的http 的post命令来发送用户输入的数据到这个dll中。注意< postfield >标识符自动的指示浏览器通过http协议来翻译用户输入的$(custid)和$(password) 变量。
---- 当用户点击登录命令的时候,这个wap手机连接到这个dll,这样使得这个dll执行如图所示的登录动作。首先,代码从Request.ContentFields 属性中提取出custid 和password字段。当被确认之后,(又专门的数据库来保存这些信息,通过遍历数据库的方法来确认它,这个遍历的函数是IsValidCustID,如下代码说示
function TMAWebModule.IsValidCustID
(CustID, Password: string): Boolean;
begin
DebugMessage('IsValidCustID:'#13'CustID="' + CustID +
#13'Password="' + Password +' "');
Result := False;
with Customer do begin
try
Open;
if Locate('custno',CustID,[]) then
if (LowerCase(CustomerState.AsString) =
LowerCase(Password)) then
Result := True;
finally
Close;
end;
end;
end;
procedure TMAWebModule.MAWebModuleLoginAction(
Sender: TObject; Request: TWebRequest;
Response: TWebResponse; var Handled: Boolean);
var
CustID, Password : string;
begin
CustID := Request.ContentFields.Values['custid'];
Password := Request.ContentFields.Values['password'];
{ Check validity of custid/password. }
with Response do begin
if IsValidCustID(CustID,Password) then
begin
DebugMessage('CustID/Password is valid.');
MAWebModuleMainMenuAction(Sender, Request,
Response, Handled);
end
else
begin
DebugMessage('Invalid CustID/Password pair.');
ContentType := MIMETypeWML;
Content := InvalidIDPageWML;
end;
end;
Handled := True;
end;
---- 由于DBDEMOS数据库不包含真实的用户ID和相应的密码,例程使用客户表Customer 中的的CustNo字段来做ID,使用State字段来作相应的密码。为测试这个意图,你可以使用如下的ID 和PASSWORD:"1221" and "HI"; "1560" and "FL"; and "1680" and "GA." 返回到浏览器上的WML代码
---- 一般的,WebBroker应用通过对在OnAction事件句柄中的Response对象的控制返回一些简单的HTML代码到浏览器中,。TWebResponse类通过Response 参数的一个Content 属性来表示,它可以接收被这个事件句柄创建的HTML代码。
---- 当用户的浏览器接收数据的时候,它根据它的MIME类型(Multipurpose Internet Mail Extensions)来处理它。TWebResponse 类的MIME类型缺省类型是"text/html",它指定Content 属性的数据类型,确实的是,HTML代码。
---- 但是,WAP应用需要WML(version1.1)的数据的MIME类型"text/vnd.wap.wml." 因此,Response 对象的ContentType属性需要被改变。注意,ContentType 属性可以被改变成任何有效的MIME类型。例如:改变该属性为"image/gif" 就会允许改动作返回一个位图的图像数据(binary.gif)。
---- 当定义好正确的MIME类型后,该动作事件的句柄就会清楚的设置Content 属性可包含有效的WML代码。由于每一个由application产生的WML页都需要一个公共的题头,这个例程定义了一个名字是WMLHeader 的常量来包含这个信息。
---- 存储返回到数据库中的数据当用户成功登录之后,用户重新回到海上探险的主菜单。通过这个菜单,用户可以选择查看客户的信息或者是订单的状态。如果客户选择用户信息的超链接,将执行MAWebModule Web 模块的 CustInfoAction方法的这个定义过的方法。
---- 首先,代码返回到随着post http命令的CustNo参数,当登录的用户的信息在客户表中被查找到以后,代码创建包括三个输入字段的WML代码。最初,三个输入字段包括客户的zip号码,城市,和state,(记着,这个state是口令). 用户可以调整这三个字段,他可以通过选择"Modify Info"命令,用户可以保存新的值返回到数据库。当用户选中这条命令的时候,将执行ModifyCustAction 方法。(见下图)
---- 在Delphi IDE 中的 MAWeb模块
procedure TMAWebModule.MAWebModuleModifyCustAction(
Sender: TObject; Request: TWebRequest;
Response: TWebResponse; var Handled: Boolean);
var CustID, State, City, Zip : string;
begin
CustID := Request.ContentFields.Values['custid'];
State := Request.ContentFields.Values['State'];
City := Request.ContentFields.Values['City'];
Zip := Request.ContentFields.Values['Zip'];
with Response do begin
ContentType := MIMETypeWML;
try
if LocateCustomer(CustID) then
begin
DebugMessage('Saving customer data:'#13 +
'CustID="' + CustID + '"'#13 +
'State="' + State + '"'#13 +
'City="' + City + '"'#13 +
'Zip="' + Zip + '"'#13);
Customer.Edit;
CustomerState.AsString := State;
CustomerCity.AsString := City;
CustomerZip.AsString := Zip;
Customer.Post;
Content := WMLHeader +
'< card id="modifyok" title="Info ' +
'Modified" newcontext="true" >' + CRLF +
' < onevent type="ontimer" >' + CRLF +
' < go method="post" ' +
'href="/scripts/ma_ooqs.dll/mainmenu" >' +
CRLF + ' < postfield name="custid" ' +
'value="' + HTTPEncode(CustID) + '"/ >' + CRLF +
' < /go >' + CRLF + ' < /onevent >' + CRLF +
' < timer value="30"/ >' + CRLF + ' < p >' +
CRLF + ' < b >Customer info succesfully '+
'modified.< /b >< br/ >' + CRLF + ' < /p >' + CRLF +
'< /card >' + CRLF + CRLF + '< /wml >' + CRLF;
end
else
Content := InvalidIDPageWML;
finally
Customer.Close;
end;
end;
Handled := True;
end;
---- figure6:存储用户输入的数据到customer表中。
---- 这段代码从Request.ContentFields 属性中提取新的客户信息,然后在Customer 表中查找正确的客户记录,然后调用Edit方法把这个表转入dsEdit状态,设置字段值(fields),最后调用Post方法提交记录。
---- 测试海上冒险程序为测试这个程序,你需要有一个Web服务器,它上面能运行ISAPI系统。这个例程已经在Microsoft IIS4.0下测试通过,但她应该也能够在其他的兼容产品上或者是IIS的其他版本的系统上运行。除了这台Web服务器之外,你还需要下在并安装Nokia WAP Toolkit version 1 。(截稿时,Nokia WAP Toolkit 1.3 的测试版本提供下载)。这个产品可以从Nokia的WAP站点免费下载 (Http://www.delphizine.com/include/Click_Redir.asp?Url=http://www.forum.nokia.com/. ) 这个开发工具不需要安装在和WEB服务器的同一台计算机上,因为说有它需要的仅仅是能通过IP网络连接到WEB服务器。当这个WAP开发工具打开时,他会显示一个欢迎项目(参见图2)。这个开发系统能模拟两个移动电话模块。为实现MAOOQS,使用这个开发工具参数菜单命令选择Nokia 6110型的电话。
---- 为定位这个程序的登录屏幕,从Go菜单的中选中Load Location command ,键入登录的login.wml文件的URL:http://localhost/login.wml.注意在做这些操作之前,这个login.wml文件需要被拷贝到web服务器的publish目录的根目录下面,不用说这时这台web服务器比喻已经成功的运行MAOOQS。
---- 下图显示的是我们的测试的海上探险应用程序的相关的屏幕。当这个login.wml文件被成功的登录之后,你将很快看到步骤1中的"Welcome to" 屏幕,几秒钟后,屏幕自动切换到step 2,为在输入字段中输入文本,点击wap电话键盘区的左上角的蓝色的"/"符号。点中之后,wap电话屏幕的左下角写的是"Edit",如果它写的是"Login",你需要点击上、下箭头按钮,因为这时不是编辑状态。
---- 当成功点中Edit 命令时,屏幕显示如step3所示的完整的文本输入编辑器。customer ID 字段只能输入数字,所以点击数字键一一输入相应的数字,如果你输入出错的话,右边的"/" 可以擦去最后一个字符。password 字段中可以输入字母和数字,所以你就输入相应的的password,有时你可能需要重复点击数字键以输入字母,例如:如果你需要输入字母"B",你需要快速点击按钮"1"两次惨能够输入这个字母。如果你使用移动电话输入文本的话,你就必须知道这种输入文本的方法。
---- 上图是Nokia 6110手机扩大的屏幕,这些step简介在MAOOQS程序中出现的次序从dll来的请求数据
---- 当the customer ID 和password 成功输入后,你将发现屏幕又出现了step 2中的画面。 稍稍等待"Login" 命令被激活,然后点击"/"按钮来选中命令,这将处理这个登录过程选中Login 命令来使得这台wap移动电话连接到web服务器的/scripts/ 目录中的 MA_OOQS ISAPI应用程序,当然了,这时ISAPI DLL 已经被放置到web服务器的/scripts/ 目录中,并且这台web服务器有足够的权限正常执行这些dll,如果每一步都很正常的话,这台wap移动电话就会接受到从dll返回回来的正常的wml数据。如果输入了不正确的customer ID 或者 password两者中任一项的话,就会显示如 setp 4中所示的屏幕,显示出不正确的ID屏幕;正常的话,显示如step 5中所示的主菜单。
---- wap移动电话上的箭头键是的你可以选择菜单命令中的项。点击"/"按钮,屏幕会显示如step 6所使得用户信息的屏幕,或者是订单细节的如step 9中的屏幕。再次按下"/"允许你在这三个页面之间相互切换。如果你使用如step 7中的屏幕中的Modify Info 命令来改变客户的信息的话,你将看到如setp 8所示的调整窗口。值得注意的是,wap设备通常没有"log out"
本文地址:http://com.8s8s.com/it/it6354.htm