构建适用不同客户端的J2EE网络应用程序

  • 来源: 天极yesky 作者: 若水   2008-05-07/15:09
  • 引言:学习如何使用构造不仅支持浏览器而且还支持WAP、IMODE及其他客户端设备的国际化网络应用程序。

    在今天竞争日趋激烈的世界上,许多商业行为变得越来越全球化,以便达到最大的收益。 这就成了一个问题,因为由那些商业机构开发的应用程序必须适用于许多国家里使用不同语言的消费者。 使事情变得越来越复杂的是,以前功能有限的应用程序客户端—台式电脑和浏览器—也在快速的发展。新的客户端类型包括便携计算机、手提电话和其它小型设备。所以,国际经营机构有必要增加开发和设计成本合算、可升级并可维护的具有把内容是用多种语言发送到多种设备上的解决方案--换句话说,就是在全球经济圈中把应用程序发送到不同的客户端上。

    本文是一个个案研究,设计并且开发一个基于J2EE的可扩充的、可升级的并且经济合算的应用程序以满足不同客户端的需要。样品应用程序的目标不仅是个人计算机用户而且可以是WAP移动式电话和iMode电话,而且它使用可针对各个地区需要定制和可本地化的国际化技术来迎合国际社会。


    图1:一个典型的应用程序方案,使用不同的运行于一个公共服务器的基于国际互联网络的应用程序的用户设备。

    使用根据客户端语言与设备的多种格式和语言应答的需要意味着必须执行两个主要任务的服务器应用程序:

    1. 为提出请求的设备确定适当的输出格式,举例来说:

    · 如果请求是从Web上发出的,那么输出HTML格式。

    · 如果请求是从一个iMode设备上发出的,那么输出CHTML格式。

    · 如果请求是从一个WAP设备上发出的,那么输出WML格式。

    2. 支持I18N(国际化)。 那意味着输出将使用适当的语言,而且日期和数字格式也应该与客户端所在的地区匹配。

    名为“网关(gateway)”的专用服务器软件模块把客户端的请求翻译成为HTTP请求。 举例来说,一个WAP网关负责把WSP请求转换成为HTTP请求(反之亦然)以及分析和解释应答。 同样地,使用一个VoiceXML请求,由一个Voice浏览器组成的网关负责识别语言和DTMF输入,把它转换成为一种标准请求格式,并且把VoiceXML应答转换成为语音。

    一些可能存在的问题

    表格1给了一些不同的客户应用程序的上会出现的问题以及可能的解决方案。

    需要考虑的问题 参考答案
    怎样为多用户客户端提供支持? 为所有的用户客户端使用公共的服务器端代码。
    使用XML和Xslt。 XML文件包含为所有的客户端所共用的数据。XSLT执行把XML改变成为适合于各个用户端的格式的转化请求。

    设置的生成的应答依靠适用于请求的设备的MIME类型。举例来说,为了响应一个WML请求,MIME类型必须被设置为text/vnd.wap.wml。
    在服务器还是在客户端执行XSLT转化? 总是使用服务器端转化。并不是所有的客户端都支持客户端转换。
    怎样为I18N客户端提供支持? 必须使用UTF-8编码格式。
    使用ResourceBundle和Message Bundle类以及java.text程序包。
    应用程序可以使用cookies作为状态管理吗? 不可以。
    不使用cookies,怎样管理session数据? 使用URL重写不支持cookies的客户端。
    使用绝对URL还是相对URL来引用服务器资源? 使用绝对的URL,以避免不支持相对URL的客户端潜在的问题。

    应用程序实例

    在这个简单的实例情景中,应用程序中的第一个JSP页面显示一个包含超链接的页面。 当用户点击一个连接时,应用程序作出响应,连接到一个特殊的页面。 为了接受选择,另一个页面将成为结果页。 正如你看见的,例程中的内容是极其地简单,所以你可以专心于应用程序怎样产生适当的语言与针对设备的不同的响应。这个应用程序的完整的请求/响应部分是由四个主要组分组成的:

    · 一个提供处理请求和驱动应答序列的代码逻辑的JSP页面。

    · 一个XML生成程序,负责生成一个XML页面。

    · 一个XSL样式表,针对提出请求的客户端有不同格式的应答。 XSLT用于服务器端转化。

    · 一个Resource Bundle文件,提供I18N支持。


    图3显示了顶级应用程序配置结构,并解释了组件之间的配置顺序和相互关系。

    JSP文件的结构和处理

    在示例应用程序中,JSP页面负责:

    · 识别客户端。

    · 创建应答MIME设置。

    · 确定页面中将生成什么样的语言。

    · 产生一个请求来生成XML页面

    · 应用适当的XSLT样式表来产生XML页面。 #p#分页标题#e#

    比如,假定一个客户端对Options.jsp文件(示例应用程序的第一个页面)提出了一个请求。 客户端把所使用的语言和国家名作为一个参数(URL参数)传入服务器。 如果服务器上的JSP页面不能接受(或者不能识别)客户端的语言和国家设置,那么应用程序就使用美国英语来显示响应。 下面的程序代码段说明一个JSP页面怎样从请求中取得语言和国家信息。

    /*检查应答中将显示的语言 默认情况下,将使用美国英语来显示应答 */

    if((language = request.getParameter("language"))==null) language="en";

    if((country = request.getParameter("country"))==null) country="US";

    country = country.toUpperCase();

    基于客户端程序,JSP页面设置应答的MIME类型,识别用于产生的XML的XSLT样式表,并且设置适当的pageType值,XML生成程序使用这个值来在XML生成程序中找到适当的Resource Bundle文件。

    另外,应用程序将足够智能化以识别相应的应答格式。 比如,下列代码片断检查一个浏览器客户端,如果发现的话,执行某些具体的处理过程。

    String userAgent = request.getHeader("User-Agent");

    /* 识别用户设备∶

    1. 设置为产生XML的pageType变量。 在这个时候,应用程序随语言、国家和页面类型设置来从资源包中取得相应的条目。

    2.设置contentType变量。 应用程序根据识别的用户设备来设置MIME头。

    3. 设置xslName变量。 这是用于把XML转换为页面的XSLT文件的文件名。

    */

    if(userAgent.startsWith("Mozilla"))

    {

    pageType="Web"; contentType="text/html;charset=UTF-8";

    xslName="articles-html-form.xsl";

    }

    其他的用户设备发送不同的Header。例如,你可以使用下面的程序代码识别iMode用户设备(可以在 wapprofit.com模拟器中验证)∶

    userAgent.startsWith("Microsoft URL")

    而且你也可以使用下面的代码来识别WAP(Nokia工具包)用户设备:

    userAgent.startsWith("Nokia")

    你必须使用UTF-8字符集来支持I18N。

    此时,应用程序已经识别用户设备和语言,所以应用程序可以产生一个XML页面。 为了初始化XML的生成,JSP调用一个XML生成程序类方法,例如OptionsXML类的getOptionXML()方法,来根据请求返回一个包含数据的XML字符串。

    /* 调用JSP的一个私有方法来根据用户设备产生XML和应用一个XSL样式表来产生输出。 */

    showPage(pageType, language, country, response, contentType, xslName);

    showPage()方法根据pageType、语言和国家设置来产生XML页面。 它应用特定的XSLT样式表来生成XML然后把格式化了的应答发回用户设备。

    try

    {

    response.setContentType(contentType);

    response.getOutputStream().flush();

    TransformerFactory tFactory = TransformerFactory.newInstance();

    String str = OptionsXML.getOptionsXML(pageType, language, country,response);

    StringReader sReader = new StringReader(str);

    StreamSource xml = new StreamSource(sReader) ;

    StreamSource xsl = new StreamSource(xslName) ;

    Transformer transformer = tFactory.newTransformer(xsl);

    StreamResult result = new StreamResult(response.getOutputStream()) ;

    transformer.transform(xml, result);

    }

    catch(Exception e)

    {}

    Option.jsp 代码

    <%@ page import="java.util.*" %>

    <%@ page import="java.net.*" %>

    <%@ page import="import org.xml.sax.*" %>

    <%@ page import="javax.xml.transform.TransformerFactory" %>

    <%@ page import="javax.xml.transform.Transformer" %>

    <%@ page import="javax.xml.transform.stream.StreamSource" %>

    <%@ page import="javax.xml.transform.stream.StreamResult" %>

    <%@ page import="javax.xml.transform.TransformerException" %>
    #p#分页标题#e#
    <%@ page import="javax.xml.transform.TransformerConfigurationException" %>

    <%@ page import="wayne.articles.xmlgen.*"%>

    <% String pageType="Web";

    String userAgent = request.getHeader("User-Agent");

    String contentType="text/html;charset=UTF-8";

    String xslName="articles-html-form.xsl";

    String language="en";

    String country="US";

    if((language = request.getParameter("language"))==null)

    language="en";

    if((country = request.getParameter("country"))==null)

    country="US";

    country = country.toUpperCase();

    if(userAgent.startsWith("Mozilla")) {

    pageType="Web";

    contentType="text/html;charset=UTF-8";

    xslName="articles-html-form.xsl";

    }

    else if(userAgent.startsWith("Microsoft URL")) {

    pageType="IMode";

    contentType="text/html;charset=UTF-8";

    xslName="articles-imode-form.xsl";

    }

    else if(userAgent.startsWith("Nokia"))

    {

    pageType="Wap";

    contentType="text/vnd.wap.wml";

    xslName="articles-wml-form.xsl";

    }

    showPage(pageType,language,country, response, contentType, xslName);

    %>

    <%

    private void showPage(String pageType, String language, String country, HttpServletResponse response,String contentType, String xslName)

    {

    try

    {

    response.setContentType(contentType);

    response.getOutputStream().flush();

    TransformerFactory tFactory = TransformerFactory.newInstance();

    String str = OptionsXML.getOptionsXML(pageType, language, country,response);

    StringReader sReader = new StringReader(str);

    StreamSource xml = new StreamSource(sReader) ;

    StreamSource xsl = new StreamSource(xslName) ;

    Transformer transformer = tFactory.newTransformer(xsl);

    StreamResult result = new StreamResult(response.getOutputStream()) ;

    transformer.transform(xml, result);

    }

    catch(Exception e)

    {}

    }

    %>

    YourResponse.jsp 代码:

    <%@ page import="java.util.*" %>

    <%@ page import="java.net.*" %>

    <%@ page import="import org.xml.sax.*" %>

    <%@ page import="javax.xml.transform.TransformerFactory" %>

    <%@ page import="javax.xml.transform.Transformer" %>

    <%@ page import="javax.xml.transform.stream.StreamSource" %>

    <%@ page import="javax.xml.transform.stream.StreamResult" %>

    <%@ page import="javax.xml.transform.TransformerException" %>

    <%@ page import="javax.xml.transform.TransformerConfigurationException" %>

    <%@ page import="wayne.articles.xmlgen.*"%>

    <%

    String pageType="Web";

    String userAgent = request.getHeader("User-Agent");

    String contentType="text/html;charset=UTF-8";

    String xslName="articles-html-form.xsl";

    String language="en";

    String country="US";

    if((language = request.getParameter("language"))==null)

    language="en";

    if((country = request.getParameter("country"))==null)

    country="US";

    country = country.toUpperCase();

    int optionid = 1;

    try

    {

    optionid = Integer.parseInt(request.getParameter("optionType"));

    }

    catch(Exception e)

    {

    optionid = 1;

    }

    System.out.println("user Agent = " + userAgent);

    if(userAgent.startsWith("Mozilla"))

    {

    pageType="Web";

    contentType="text/html;charset=UTF-8";

    xslName="articles-html-form.xsl";

    }

    else if(userAgent.startsWith("Microsoft URL"))

    {

    System.out.println("entered");

    pageType="IMode";

    contentType="text/html;charset=UTF-8";

    xslName="articles-imode-form.xsl";

    }

    else if(userAgent.startsWith("Nokia"))

    {

    pageType="Wap";

    contentType="text/vnd.wap.wml";

    xslName="articles-wml-form.xsl";

    }

    showPage(pageType,language,country, response, optionid, contentType, xslName);

    %>

    <%
    #p#分页标题#e#
    private void showPage(String pageType,String language,String country, HttpServletResponse response, int optionid,String contentType, String xslName)

    {

    try

    {

    response.setContentType(contentType);

    response.getOutputStream().flush();

    TransformerFactory tFactory = TransformerFactory.newInstance();

    String str = YourResponseXML.getYourResponseXML(pageType,language,country,response, optionid);

    StringReader sReader = new StringReader(str);

    StreamSource xml = new StreamSource(sReader) ;

    StreamSource xsl = new StreamSource(xslName) ;

    Transformer transformer = tFactory.newTransformer(xsl);

    StreamResult result = new StreamResult(response.getOutputStream()) ;

    transformer.transform(xml, result); } catch(Exception e){}

    }

    %>

     

     产生XML的组件

    XML生成程序是一个由一套根据应答产生相应的XML页面的类组成的组件。 例如,OptionsXML.java类有一个getOptionsXML()静态方法,用来使用指定的语言和请求设备所需要的内容来产生Options.jsp文件。

    方法参数是pagetype(" Web "、" Wap "或者" iMode ")、language、country和一个HttpResponse对象,这个对象是向客户端写应答所用的,举例来说:

    OptionsXML.getOptionsXML(pageType, language, country, response);

    XML生成程序类首先创建一地区对象然后加载需要的资源包(Resource Bundle)文件。

    //创建地区和资源包对象

    Locale locale = new Locale(language,country);

    ResourceBundle rb = ResourceBundle.getBundle("ArticlesGUI",locale);

    在前面这小段代码中,“ArticlesGUI”是资源文件名。 locale实例定义了资源文件的后缀。 比如说,一个日文请求将使用ArticlesGUI_ja_JP.properties资源包文件。 同样地,对于一个英语请求,资源包文件将是ArticlesGUI_en_US.properties。

    想要获取Java应用程序中的更多的国际化信息,请访问http://java.sun.com/products/jdk/1.1/docs/guide/intl/。

    在加载适当的资源包文件之后,JSP页面实例化一个GenerateXML对象。 在完全的国际化应用程序中,所有的文字--甚至栏目标签、按钮文字和消息都是从资源文件中取得的,详细的请看下面的程序代码。 这个程序代码段添加一个页面标题、一个表单元素和一个超链接到页面中。

    String sb="";

    xml.addPageTitle(rb.getString(pageType+"_Options_Page_Heading"));

    Element form = xml.addForm(1, "optionform",true);

    xml.addLink(1,"_self", rb.getString(pageType+"_Options_Page_Option_1"), " ", url+"YourResponse.jsp?optionType=1&language=" +language+"&country="+country, rb.getString(pageType+"_Options_Page_Option_1"), form,true);

    sb = xml.getGeneratedXMLString();
     

    XSL/XSLT所扮演的角色

    XSL在这个应用程序中扮演举足轻重的角色,负责把产生的XML文件转化为一个特定用户设备上所用的格式。 应用程序使用服务器端XML转换而不是客户端转换,这是因为∶

    · 并不是所有的客户端都安装了XML语法分析程序。或者安装了也不一定都可用。 分析服务器上的XML消除了对客户端的依赖性,使应用程序更加容易支持任何用户设备。

    · XSL技术还没有完全成熟,标准还没有固定;所以不同的客户端可能会使用不同的方法转换XML。 使用服务器端转化就可以避免上述这些问题。

    因为这个应用程序很小,只有一个非常简单的图形用户界面,所以每个用户设备之需要一个XSL样式表:

    · articles-html-form.xsl —用于生成HTML (Web)

    · articles-wml-form.xsl —用于生成WML (WAP)

    · articles-imode-form.xsl —用于生成CHTML (iMode)

    然而,这个应用程序的结构仍然可以扩展。 随着图形用户界面的复杂性的增加,你可以为相对于每种用户设备格式的每个页面编写不同的XSL样式表。 代码段1是WML特定的样式表articles-wml-form.xsl中的一段。#p#分页标题#e#

    代码段1:

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" media-type="text/vnd.wap.wml" doctype-public="-//WAPFORUM//DTD WML 1.1//EN" doctype-system="http://www.wapforum.org/DTD/wml_1.1.xml" />

    <xsl:template match="/">
    <wml>
    <xsl:apply-templates select="WAYNE-ARTICLES-XML" />
    </wml>
    </xsl:template>


    <xsl:template match="WAYNE-ARTICLES-XML">
    <xsl:variable name="ptitle">
    <xsl:value-of select="self::WAYNE-ARTICLES-XML/PAGE-TITLE"/>
    </xsl:variable>


    <xsl:for-each select="FORM">
    <xsl:variable name="formname">
    <xsl:value-of select="self::FORM/attribute::Name"/>
    </xsl:variable>
    <xsl:sort order="ascending" select="FIELD/@SeqNo" />
    <card title="{$ptitle}" id="{$formname}">
    <p align="center">
    <strong><xsl:value-of select="$ptitle"/></strong><br/>
    <xsl:apply-templates select="FIELD" />
    </p>
    </card>
    </xsl:for-each>
    </xsl:template>

    <xsl:template match="FIELD">
    <xsl:variable name="lname">
    <xsl:value-of select="self::FIELD/LABEL-NAME"/>
    </xsl:variable>

    <xsl:variable name="value">
    <xsl:value-of select="self::FIELD/VALUE"/>
    </xsl:variable>

    <xsl:variable name="name">
    <xsl:value-of select="self::FIELD/attribute::Name"/>
    </xsl:variable>

    <xsl:variable name="length">
    <xsl:value-of select="self::FIELD/attribute::Length"/>
    </xsl:variable>


    <xsl:variable name="ftype">
    <xsl:value-of select="self::FIELD/attribute::Type"/>
    </xsl:variable>

    <xsl:if test="self::FIELD/attribute::Type='TEXT'">
    <strong><xsl:value-of select="$lname"/></strong>
    <input maxlength="{$length}" size="10" format="{$length}m" value="{$value}" type="text" name="{$name}"/>
    <br/>
    </xsl:if>


    <xsl:if test="self::FIELD/attribute::Type='PASSWORD'">
    <strong><xsl:value-of select="$lname"/></strong>
    <input maxlength="{$length}" size="10" format="{$length}m" value="{$value}" type="password" name="{$name}"/>
    <br/>
    </xsl:if>

    <xsl:if test="self::FIELD/attribute::Type='S-TEXT'">
    <strong><xsl:value-of select="$lname"/></strong>
    <xsl:value-of select="$value"/>
    <br/>
    </xsl:if>


    <xsl:if test="self::FIELD/attribute::Type='LINK'">
    <strong><xsl:value-of select="$lname"/></strong>
    <xsl:variable name="target">
    <xsl:value-of select="self::FIELD/attribute::Target" />
    </xsl:variable>

    <xsl:variable name="alt">
    <xsl:value-of select="self::FIELD/attribute::Alt" />
    </xsl:variable>

    <xsl:variable name="dname">
    <xsl:value-of select="DISPLAY-NAME"/>
    </xsl:variable>
    <a title="{$alt}" href="{$value}"><xsl:value-of select="$dname"/></a>
    <br/>
    </xsl:if>


    <xsl:if test="self::FIELD/attribute::Type='RADIO'">
    <strong><xsl:value-of select="$lname"/></strong>
    <select name="{$name}" multiple="false">
    <xsl:for-each select="VALUES">
    <xsl:variable name="dname">
    <xsl:value-of select="DISPLAY-NAME"/>
    </xsl:variable>
    <xsl:variable name="cvalue">
    <xsl:value-of select="VALUE"/>
    </xsl:variable>
    <option value="{$cvalue}"><xsl:value-of select="$dname"/></option>
    </xsl:for-each>
    </select>
    <br/>
    </xsl:if>

    <xsl:if test="self::FIELD/attribute::Type='SUBMIT'">

    <xsl:variable name="formname">
    <xsl:value-of select="parent::FORM/attribute::Name"/>
    </xsl:variable>

    <xsl:variable name="formtarget">
    <xsl:value-of select="parent::FORM/attribute::Action"/>
    </xsl:variable>
    #p#分页标题#e#
    <xsl:variable name="formmethod">
    <xsl:value-of select="parent::FORM/attribute::Method"/>
    </xsl:variable>


    <do label="{$lname}" type="ACCEPT" name="{$name}">
    <go accept-charset="UTF-8" href="{$formtarget}" method="post">
    <xsl:for-each select="parent::FORM/FIELD">

    <xsl:variable name="fname">
    <xsl:value-of select="self::FIELD/attribute::Name" />
    </xsl:variable>

    <xsl:if test="self::FIELD/attribute::Type='TEXT'">
    <postfield value="${$fname}" name="{$fname}" />
    </xsl:if>

    <xsl:if test="self::FIELD/attribute::Type='HIDDEN'">
    <xsl:variable name="fvalue">
    <xsl:value-of select="self::FIELD/VALUE"/>
    </xsl:variable>
    <postfield value="{$fvalue}" name="{$fname}" />
    </xsl:if>
    <xsl:if test="self::FIELD/attribute::Type='PASSWORD'">
    <postfield value="${$fname}" name="{$fname}" />
    </xsl:if>
    <xsl:if test="self::FIELD/attribute::Type='RADIO'">
    <postfield value="${$fname}" name="{$fname}" />
    </xsl:if>
    </xsl:for-each>
    </go>
    </do>
    <br/>
    </xsl:if>

    <xsl:if test="self::FIELD/attribute::Type='RESET'">

    <xsl:variable name="formname">
    <xsl:value-of select="parent::FORM/attribute::Name"/>
    </xsl:variable>

    <xsl:variable name="formtarget">
    <xsl:value-of select="parent::FORM/attribute::Action"/>
    </xsl:variable>

    <xsl:variable name="formmethod">
    <xsl:value-of select="parent::FORM/attribute::Method"/>
    </xsl:variable>

    <do label="{$lname}" type="ACCEPT" name="{$name}">
    <refresh>
    <xsl:for-each select="parent::FORM/FIELD">
    <xsl:variable name="fname">
    <xsl:value-of select="self::FIELD/attribute::Name" />
    </xsl:variable>

    <xsl:if test="self::FIELD/attribute::Type='TEXT'">
    <setvar value="" name="{$fname}" />
    </xsl:if>
    <xsl:if test="self::FIELD/attribute::Type='PASSWORD'">
    <setvar value="" name="{$fname}" />
    </xsl:if>
    </xsl:for-each>
    </refresh>
    </do>
    <br/>
    </xsl:if>
    </xsl:template>
    </xsl:stylesheet>
     

    Sun公司的应用程序接口在例程中被大量使用。 请访问Sun的Java XML下载页(http://java.sun.com/xml/download.html),下载API和技术文档。 这样你就能更加清楚的分析示例程序代码,有助于你了解转化是怎样发生的。

    XSL/XSLT变换技术的细节超出本文讨论的范围,具体细节请大家查询相应的资料。

    使用资源包

    示例应用程序使用资源包来提供I18N支持。 象前面提到的ArticlesGUI_ja_JP.properties文件,资源包文件包含了基于客户端的语言和请求者的设备应答的特定的值。举例来说,应用程序的初始的选择页面基于用户设备显示不同的标题,分别用于Web、WAP和iMode客户端。所以,选择页面资源包文件包含三个不同的" _Options_Page_Heading "属性-分别用于Web、WAP和iMode用户设备。 这里是ArticlesGUI_ja_JP.properties文件的一个节选。

    // 选择页面

    Web_Options_Page_Heading=\u65e5\u672c\Wayne's Demo

    Wap_Options_Page_Heading=\u65e5\u672c\Demo

    WAP IMode_Options_Page_Heading=\u65e5\u672c\Demo -- iMode
     

    下面的代码段通过添加一个前缀到定义在JSP文件中的pagetype变量值,来取得用于给定用户设备相应的页标题。 记住,JSP页面设置pagetype变量的值为"Wap"、"Web"或者"iMode"然后把这个变量传入XML生成程序类。

    rb.getString(pageType+"_Options_Page_Heading");

    这个方案让你产生包含适合于目标用户设备的值的XML页面。 产生的XML文件是普通的、公用的,可用于所用的请求,然后在XSL转换期间被转化成为用户设备的特定格式。 使用这种方式来分离页面产生代码可以给你提供用于不同的用户设备的不同的值的灵活性。

    为额外的用户设备和语言添加支持

    正如你所看到的,这个应用程序结构使为其它用户设备和语言添加支持变得很方便。 下面就是要扩展这个应用程序以便支持其它的语言或者用户设备的步骤。

    为其他的用户设备添加支持
    #p#分页标题#e#
    · 修改JSP文件,检查新用户设备。

    · 为pageType变量创建一个新的值来识别新用户设备,然后在JSP文件中设置值。 比如,如果你想添加对于VoiceXML浏览器的支持,那么pagetype变量的值可以是"VOICE"。

    · 创建一个用于新用户设备的XSL样式表

    · 在新用户设备对应的资源包文件中添加新关键字值条目。

    为其他的语言添加支持

    创建一个对应于目标语言和国家的新的资源包文件。 例如,为了提供韩语支持,你将创建一个名为ArticlesGUI_ko_KO.properties的文件,然后使用Unicode格式为所有的关键值编写相应的条目。 用于访问使用的韩语的应用程序的话,那么URL的起始字符就是:

    http://<machine name>:<port>/Options.jsp?language=ko&country=KO

    处理图像和日期

    你甚至可以使用资源包提供语言和用户设备特定的图像。 例如:

    //使用资源包定位用户设备特定的图像格式

    Web_Welcome_Image=web.gif

    Wap_Welcome_Image=wap.wbmp

    Imode_Welcome_Image=imode.jpg

    注意,你使用同样的pagetype变量和地区对象取得适当的图像。 对于国际化日期、数字和货币都是使用java.text程序包。 下面的程序代码示范如何检索一个地区特定的日期。

    //对于日文和日本的日期

    Locale locale = new Locale("ja","JP");

    Date today = new Date();

    DateFormat dateFormatter;
    /*按照地区创建日期*/

    dateFormatter = DateFormat.getDateInstance(DateFormat.FULL,locale);

    str+=dateFormatter.format(today);

    在上面我们已经看到了用于处理和显示国际化的、未知平台的内容的一些强有力的技术,使用这些技术,我们可以使用J2EE、XML和XLST设计应用程序以支持不同类型和语言的客户端设备,而且是你的应用程序不仅可以真正的实现全球化,而且可以针对未知的客户端类型做到可扩展和可修改。 你甚至可以编写一个智能化更加高的Java类来操作showPage()方法的处理。 那么可能性将是无尽的!

    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多