WAP建站入门教程
来源:yesky
被读3031次
转载请注明出处-中国设计秀-cnwebshow.com
先看一个简单的例子程序:
图 2-35 使用Unicode的中文WML页面
图 2-36 没有使用Unicode的中文WML页面
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<% response.setContentType("text/vnd.wap.wml"); %>
<wml>
<card id="start">
<do type="accept">
<go href="index.jsp#test"/>
</do>
<p>
JSP Test:<br/>
Press accept to continue!<br/>
</p>
</card>
<card id="test">
<do type="prev">
<prev/>
</do>
<%
out.println("<p>");
out.println("Hello from script code!<br/>");
out.println("</p>");
%>
</card>
</wml>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<% response.setContentType("text/vnd.wap.wml"); %>
<wml>
<card id="start">
<do type="accept">
<go href="index.jsp#test"/>
</do>
<p>
JSP Test:<br/>
Press accept to continue!<br/>
</p>
</card>
<card id="test">
<do type="prev">
<prev/>
</do>
<%
out.println("<p>");
out.println("Hello from script code!<br/>");
out.println("</p>");
%>
</card>
</wml>
下面将要演示使用WML和Java Server API如何简单快速地在WAP终端上生成动态的WML页面。这里将不再去讲每个WML标记的作用,而是给出一个简单的例子。这个例子体现出整个语言的特点。
这个JSP例子显示了为一个移动用户定时更新约会的例子,例如:做一个给家里打电话的应用程序。这个应用是在Windows NT下使用Java Server Web Development Kit(JSWDK)1.01和JSWDK配套的服务端工具,来建立的JSP页面。使用Nokia WAP Toolkit 1.2测试和浏览应用。
一个典型的路径还包括在移动电话和WAP内容服务之间的一个WAP网关。这样安排的主要原因是要对WML进行编码,这样来适应其窄带的特点。但是Nokia WAP Toolkit包含了这样一个编译器,因此它可以直接从HTTP服务器提取WML内容(在例子里是从服务端工具上来取的)。
当建立WAP应用的时候,必须记住一点。WAP设备的显示屏幕很小——典型的只有4行12个字符,不要使用过多的滚动。这样会使用户十分烦心。数据的输入功能也十分有限。而且设备的RAM有限,CPU的能力有限。并且现在无线网络的带宽有限而且高延时。因此WAP的应用程序应当短小,简单。
应用程序包括两个页面。第一个是“pick_appointment.jsp”。它有一个选择卡片。当用户选择了其中的一个约会时间的时候,就会进入到“show_appointment_data.jsp”页面(中间还传递了约会的ID号)。第二个页面有两个卡片。第一个显示会面的时间,第二个显示数据输入,允许工程师通过输入ID取消约会。
动态的约会数据是通过JavaBean的实例来取得的。在这里没有它的代码,总的来说是通过JDBC连接到数据库的过程。取消的过程是通过Servlet来操作的,在这里其程序也没有显示。既然用户可能随时取消某个约会,因此需要定时地刷新“pick_appointment.jsp”。
这个JSP例子显示了为一个移动用户定时更新约会的例子,例如:做一个给家里打电话的应用程序。这个应用是在Windows NT下使用Java Server Web Development Kit(JSWDK)1.01和JSWDK配套的服务端工具,来建立的JSP页面。使用Nokia WAP Toolkit 1.2测试和浏览应用。
一个典型的路径还包括在移动电话和WAP内容服务之间的一个WAP网关。这样安排的主要原因是要对WML进行编码,这样来适应其窄带的特点。但是Nokia WAP Toolkit包含了这样一个编译器,因此它可以直接从HTTP服务器提取WML内容(在例子里是从服务端工具上来取的)。
当建立WAP应用的时候,必须记住一点。WAP设备的显示屏幕很小——典型的只有4行12个字符,不要使用过多的滚动。这样会使用户十分烦心。数据的输入功能也十分有限。而且设备的RAM有限,CPU的能力有限。并且现在无线网络的带宽有限而且高延时。因此WAP的应用程序应当短小,简单。
应用程序包括两个页面。第一个是“pick_appointment.jsp”。它有一个选择卡片。当用户选择了其中的一个约会时间的时候,就会进入到“show_appointment_data.jsp”页面(中间还传递了约会的ID号)。第二个页面有两个卡片。第一个显示会面的时间,第二个显示数据输入,允许工程师通过输入ID取消约会。
动态的约会数据是通过JavaBean的实例来取得的。在这里没有它的代码,总的来说是通过JDBC连接到数据库的过程。取消的过程是通过Servlet来操作的,在这里其程序也没有显示。既然用户可能随时取消某个约会,因此需要定时地刷新“pick_appointment.jsp”。
pick_appointment.jsp
<%@ page language="java" contentType="text/vnd.wap.wml" %>
<jsp:useBean id="appointmentBean" class="mwebber.samples.AppointmentBean" scope="application" />
<%!
// This convenience method builds our <option> elements, one for each appointment.
private String getOptions(mwebber.samples.AppointmentBean appointmentBean)
{
StringBuffer sb = new StringBuffer();
int[] appointmentIDs = appointmentBean.getAppointmentIDs();
for(int i=0; i<appointmentIDs.length; i++)
{
sb.append("<option onpick="show_appointment_data.jsp?id=");
sb.append(i);
sb.append("">");
sb.append(appointmentBean.getAppointmentTime(i));
sb.append("</option>");
}
return sb.toString();
}
%>
<%! String strXMLPrologue = "<?xml version="1.0"?>"; %>
<%-- WML CONTENT BEGINS --%>
<%= strXMLPrologue %>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card id="pick" title="Appointments">
<!-- Refresh the deck every minute -->
<onevent type="ontimer">
<go href="pick_appointment.jsp"/>
</onevent>
<timer value="600"/>
<!-- Display a widget to navigate back by one in the history stack -->
<do type="prev">
<prev/>
</do>
<!-- Display the "select" widget of appointments to pick -->
<p>
<select title="Appointments">
<%= getOptions(appointmentBean) %>
</select>
</p>
</card>
</wml>
<%-- WML CONTENT ENDS --%>
<%@ page language="java" contentType="text/vnd.wap.wml" %>
<jsp:useBean id="appointmentBean" class="mwebber.samples.AppointmentBean" scope="application" />
<%!
// This convenience method builds our <option> elements, one for each appointment.
private String getOptions(mwebber.samples.AppointmentBean appointmentBean)
{
StringBuffer sb = new StringBuffer();
int[] appointmentIDs = appointmentBean.getAppointmentIDs();
for(int i=0; i<appointmentIDs.length; i++)
{
sb.append("<option onpick="show_appointment_data.jsp?id=");
sb.append(i);
sb.append("">");
sb.append(appointmentBean.getAppointmentTime(i));
sb.append("</option>");
}
return sb.toString();
}
%>
<%! String strXMLPrologue = "<?xml version="1.0"?>"; %>
<%-- WML CONTENT BEGINS --%>
<%= strXMLPrologue %>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card id="pick" title="Appointments">
<!-- Refresh the deck every minute -->
<onevent type="ontimer">
<go href="pick_appointment.jsp"/>
</onevent>
<timer value="600"/>
<!-- Display a widget to navigate back by one in the history stack -->
<do type="prev">
<prev/>
</do>
<!-- Display the "select" widget of appointments to pick -->
<p>
<select title="Appointments">
<%= getOptions(appointmentBean) %>
</select>
</p>
</card>
</wml>
<%-- WML CONTENT ENDS --%>
show_appointment_data.jsp
<%@ page language="java" contentType="text/vnd.wap.wml" %>
<jsp:useBean id="appointmentBean" class="mwebber.samples.AppointmentBean" scope="application" />
<%
// Grab the "id" parameter, using the in-built reference to the request object.
int intAppointmentID = Integer.parseInt(request.getParameter("id"));
%>
<%! String strXMLPrologue = "<?xml version="1.0"?>"; %>
<%-- WML CONTENT BEGINS --%>
<%= strXMLPrologue %>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card id="main_data" title="Main Data">
<p align="center">
<b>
<%= appointmentBean.getAppointmentTime(intAppointmentID) %>
</b>
</p>
<p>
<br/>
<%= appointmentBean.getAppointmentDetails(intAppointmentID) %>
<br/>
<a href="#check_off">Check off this appointment</a><br/>
<a href="http://localhost:8080/pick_appointment.jsp">Back to appointments list</a>
</p>
</card>
<card id="check_off" title="Check Off">
<!-- Set up a widget to send the input field data to the server -->
<do type="accept">
<go href="/servlet/ProcessCheckOff" method="post">
<postfield name="check_off_code" value=" $check_off_code"/>
</go>
</do>
<p>
<input name="check_off_code" emptyok="false" maxlength="6"/>
</p>
<p>
<a href="#main_data">Back to appointment data</a>
<br/>
<a href="http://localhost:8080/pick_appointment.jsp">Back to appointments list</a>
</p>
</card>
</wml>
<%-- WML CONTENT ENDS --%>
<%@ page language="java" contentType="text/vnd.wap.wml" %>
<jsp:useBean id="appointmentBean" class="mwebber.samples.AppointmentBean" scope="application" />
<%
// Grab the "id" parameter, using the in-built reference to the request object.
int intAppointmentID = Integer.parseInt(request.getParameter("id"));
%>
<%! String strXMLPrologue = "<?xml version="1.0"?>"; %>
<%-- WML CONTENT BEGINS --%>
<%= strXMLPrologue %>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card id="main_data" title="Main Data">
<p align="center">
<b>
<%= appointmentBean.getAppointmentTime(intAppointmentID) %>
</b>
</p>
<p>
<br/>
<%= appointmentBean.getAppointmentDetails(intAppointmentID) %>
<br/>
<a href="#check_off">Check off this appointment</a><br/>
<a href="http://localhost:8080/pick_appointment.jsp">Back to appointments list</a>
</p>
</card>
<card id="check_off" title="Check Off">
<!-- Set up a widget to send the input field data to the server -->
<do type="accept">
<go href="/servlet/ProcessCheckOff" method="post">
<postfield name="check_off_code" value=" $check_off_code"/>
</go>
</do>
<p>
<input name="check_off_code" emptyok="false" maxlength="6"/>
</p>
<p>
<a href="#main_data">Back to appointment data</a>
<br/>
<a href="http://localhost:8080/pick_appointment.jsp">Back to appointments list</a>
</p>
</card>
</wml>
<%-- WML CONTENT ENDS --%>
在每一文件的开头,都要设置正确的MIME文件类型。如果文件类型不对,那么这个页面将遭到模拟器的拒绝。在这个例子里,“text/vnd.wap.wml”表明是WML页面。其他类型例如“text/vnd.wap.wmlscript”是WMLScript源代码,而“image/vnd.wap.wbmp” 是WBMP文件。
既然WML页面是一个XML文档,因此它包含了标准的XML文件头和一个DTD头,但是“<?”和“?>”标记显然与JSP的标记有混合。因此将这一段隐藏到字符串变量当中。别忘记JSP将被编译成Java源文件,最后成为Servlet。
既然WML页面是一个XML文档,因此它包含了标准的XML文件头和一个DTD头,但是“<?”和“?>”标记显然与JSP的标记有混合。因此将这一段隐藏到字符串变量当中。别忘记JSP将被编译成Java源文件,最后成为Servlet。
GB2132转Unicode
Unicode的原理也很简单。使用“&#x”加上ASCII码的数值文本再加“;”结尾。当然要注意的是:这里所指的ASCII数值并不是简单的内存数值(或者说是GB2132编码)。例如:“饱”字,在内存里面的数值是0xb1a5,而在Unicode映射表内是0x9971。请先看下面的一段小程序。在WML页面中混有英文和中文。中文是采用Unicode书写的。
<?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="main" title="Chinese">
<p>
T;⛳
</p>
</card>
</wml>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1 //EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card id="main" title="Chinese">
<p>
T;⛳
</p>
</card>
</wml>
在Nokia WAP Toolkit中的测试结果为(图2-35所示):
图 2-35 使用Unicode的中文WML页面
可以看到“⛳”变成了“饱”字。如果用“&#b1a5;”或者直接使用GB2132编码(相当于直接书写中文)那么显示结果就可能是图2-36所示的样子。肯定要问自己,怎么会这样!原因就是在这个位置上的Unicode编码字符是个怪字符。
图 2-36 没有使用Unicode的中文WML页面
对于英文字符可以使用Unicode方式,也可以不使用。那么Unicode编码如何获得呢?
如果使用手工方式,那么可以在“附件”中找到“Unicode映射表”。打开映射表,选择“宋体”和“CJK Unified Ideograph”,在里面可以找到很多中文字符的Unicode编码。随便拷贝一个到WML文件中,百试百灵!就是使用的时候不是很方便。
如果使用Visual Basic脚本语言编写服务端程序(例如:ASP),那么问题就简单多了。可以使用AscW这个函数来解决编码的问题。以下的几个编码函数就是这样做的。
如果使用Visual C&C++编写服务端程序,那么必须使用到Windows的一个API函数:MultiButeToWideChar。这个函数可以实现Unicode的转换。
对于其他服务端脚本语言也应该有类似的函数。如果没有,那么就必须自己做一个转换工具,能把WML中的中文转换为Unicode。在MSDN提供的例子中有一个小的转换工具:Uconvert。但是好像不是很好用,不过可以研究里面的程序。在网络上有不少这样的实用小工具。
如果使用手工方式,那么可以在“附件”中找到“Unicode映射表”。打开映射表,选择“宋体”和“CJK Unified Ideograph”,在里面可以找到很多中文字符的Unicode编码。随便拷贝一个到WML文件中,百试百灵!就是使用的时候不是很方便。
如果使用Visual Basic脚本语言编写服务端程序(例如:ASP),那么问题就简单多了。可以使用AscW这个函数来解决编码的问题。以下的几个编码函数就是这样做的。
如果使用Visual C&C++编写服务端程序,那么必须使用到Windows的一个API函数:MultiButeToWideChar。这个函数可以实现Unicode的转换。
对于其他服务端脚本语言也应该有类似的函数。如果没有,那么就必须自己做一个转换工具,能把WML中的中文转换为Unicode。在MSDN提供的例子中有一个小的转换工具:Uconvert。但是好像不是很好用,不过可以研究里面的程序。在网络上有不少这样的实用小工具。
适用于ASP的转换程序
<%=replace(Server.HTMLEncode(request.form("text")),chr(13)+chr(10),"<BR>")%> >
以下是您的UNICODE码:
<textarea name="text" cols="40" rows="10">
<%=Server.HTMLEncode(unicode(request.form("text")))%>
以下是您的UNICODE码:
<textarea name="text" cols="40" rows="10">
<%=Server.HTMLEncode(unicode(request.form("text")))%>
第一个Basic程序
function unicode(str)
for i = 1 to Len(str)
c = Mid(str, i, 1)
unicode = unicode & "&#x" & Hex(AscW(c)) & ";"
next
end function
for i = 1 to Len(str)
c = Mid(str, i, 1)
unicode = unicode & "&#x" & Hex(AscW(c)) & ";"
next
end function
第二个Basic程序
function unicode(str)
dim i,j,c,i1,i2,u,fs,f,p
unicode=""
p=""
for i=1 to len(str)
c=mid(str,i,1)
j=ascw(c)
if j<0 then
j=j+65536
end if
if j>=0 and j<=128 then
if p="c" then
unicode=" "&unicode
p="e"
end if
unicode=unicode&c
else
if p="e" then
unicode=unicode&" "
p="c"
end if
unicode=unicode&"&#"&j&";"
end if
next
end function
dim i,j,c,i1,i2,u,fs,f,p
unicode=""
p=""
for i=1 to len(str)
c=mid(str,i,1)
j=ascw(c)
if j<0 then
j=j+65536
end if
if j>=0 and j<=128 then
if p="c" then
unicode=" "&unicode
p="e"
end if
unicode=unicode&c
else
if p="e" then
unicode=unicode&" "
p="c"
end if
unicode=unicode&"&#"&j&";"
end if
next
end function