您当前的位置: 首页 > 网站编程 > JSP教程 > 使用 JavaServer Pages 技术开发多语言 Web 应用程序

使用 JavaServer Pages 技术开发多语言 Web 应用程序

作者:guanchaofeng 来源:本站整理 发布时间: 2009-11-02 09:26 点击:
JavaServerPages(JSP)技术现已成为深受Web应用程序开发者欢迎的工具。使用JSP技术,开发者不需要其他的编程知识就可以设计出动态的web网页。同时,Web开发者可以使用一种可扩展的标记机制来管理基础软件组件的功能。 通过Java标准制定组织(JavaCommunityPro

使用 JavaServer Pages 技术开发多语言 Web 应用程序

  JavaServerPages(JSP)技术现已成为深受Web应用程序开发者欢迎的工具。使用JSP技术,开发者不需要其他的编程知识就可以设计出动态的web网页。同时,Web开发者可以使用一种可扩展的标记机制来管理基础软件组件的功能。
  
  通过Java标准制定组织(JavaCommunityProcess)开发的一个扩展功能可为多语言应用程序的开发提供更有力的支持。JavaServerPages标准标记库除了其他一些功能,还定义了一套可实现本地化和地区敏感(locale-sensitive)格式化的标记。
  
  行文方面,本文首先对JavaServerPages技术进行了简要介绍,以使您能够更好地理解如何使用它们解决国际化的问题。然后,我会针对多语言web应用程序的开发讨论几个核心问题,并介绍如何使用JavaServerPages技术解决它们:这些问题包括地区确定和本地化、字符编码、格式化以及解析。
  
  JavaServerPages技术
  JavaServerPages(和几种相关技术)构成了web应用程序的表示层。使用JSP技术,开发者可以创建动态的web页面,这些页面可以与商业逻辑(businesslogic)、数据库以及其他可从网络上获取的服务形成互动关系。
  
  JavaServerPages
  使用JSP技术开发的网页结合了HTML、XML或其他含有类似XML标记(这些标记与基础软件库连接)的静态内容,通常这些软件库使用Java编程语言编写。在这种环境中,非常重要的Java技术有JavaBeans组件架构(作为JSP和Java类之间的常规用途接口)、用于访问SQL数据库的Java数据库连接(JDBC)API以及各种用于XML处理的库。
  
  JSP页面本身按照servlet格式被编译为Java代码,以便执行。Servlet是web服务器的扩展,它被编译并关联至服务器,从而可以获得比脚本语言更快的执行速度。Servlet直接以Java编程语言编写,并经常与JSP网页一起使用,其中servlet作为控制部分而JSP页面作为应用程序的视图部分。
  
  JavaServerPages和底层的servlet技术为处理HTTP请求和回应信息,以及使用Cookies或URL重写进行会话维护都提供了广泛的支持。
  
  使用JSP技术的一个很重要的原因在于它可以将网页作者和应用程序开发者的工作进行分离。尽管可以将Java语句直接嵌入JSP网页,但是,开发者们已经认识到最好避免如此,而现在更倾向于使用自定义标记。
  
  JavaServerPages标准标记库
  JavaServerPages标准标记库(JSTL)包含了一系列涵盖数个功能领域的自定义操作,这些功能在JSP网页中经常被使用。该库建立在许多参与者开发自己的库时所获得的经验基础之上,它提供了一种应用程序可以依靠的标准接口,并且可以独立于他们运行的服务器之外。
  
  除了自定义标记,JSTL还引入了一种表达语言,这种语言运进一步地减少了在JSP网页中使用脚本语言的需求,同时还引进了标记库验证程序以限制在JSP网页上对脚本和标记库的使用。这种改进版本的表达语言,以及限制脚本的功能已在随后被集成到JSP2.0规范之中,所以只有使用JSP1.2时才要求JSTL。
  
  自定义操作包括的主要内容是:
  
  变量操作:“核心”库中的一些操作,可在不同的领域(网页、请求、会话和应用程序)中定义、删除变量或者将变量植入生成的页面中。
  控制流:“核心”库中的几种操作,提供了基于标记的控制流结构(例如条件和迭代器),以减少对嵌入脚本语言代码的需求。
  URL相关操作:“核心”库中的一些操作,可让JSP网页导入由URL定义的内容,可将内部形式的URL重写为外部形式(这可能包括收集会话跟踪信息)或重新定向至一个不同的网页。
  XML处理:“xml”库中的操作,包括解析XML文档并使用XPath表达式来解压缩内容,基于XPath表达式的控制流以及使用XSLT样式表进行的转换。
  关系数据库访问:“sql”库中的操作,允许web应用程序执行简单的SQL查询和更新。
  国际化和格式化(本文的中心内容):“fmt”库中的操作,支持地区确定、本地化、字符编码决定和地区敏感格式化与解析。
  地区确定和本地化
  设计多语言web应用程序时,您必须首先决定如何确定用户的语言和地区首选项,以及如何使这些首选项与该应用程序和基础的Java运行环境支持的一套地区设置相匹配。这部分首先描述了web应用程序必须具有的外部环境和要求。下一步,我们将了解相关的Java2StandardEdition(J2SE)平台提供的功能,最后我们将了解JavaServerPages标准标记库的标记如何连接到环境和J2SE中。
  
  确定用户首选项
  web应用程序有两种方法来确定用户的语言首选项:首先,它可以由浏览器使用HTTP请求报头字段Accept-Language传输至服务器的语言和地区首选项。尽管标准规定了许多语言标记,但是一般使用ISO639语言代码(如ja为日文)和ISO3166国家代码(如IT代表意大利)。浏览器通常让用户创建一个语言列表作为其首选项的一部分。然而,这种方法不太可靠;用户不一定会创建该列表,而且该列表不一定会包含该应用程序支持的地区设置。由于这些不确定性,多语言应用程序通常采用第二种方法:他们让用户直接从支持语言的列表中选择,并把选择的语言作为用户资料的一部分进行保存,或只在进行该会话的时候保存。一个好的方法是,在对用户一无所知的情况下,首先使用Accept-Language信息,在应用程序的开始页面中给予用户直接选择语言的机会。
  
  将Accept-Language地区设置主要用于语言和文化首选项是没什么意义的。例如,它们不应该被解释为表示用户居住的国家。同样,在很多情况下浏览器提供的地区设置只有一个语言代码,而一些地区敏感的功能(例如,日期格式)则随着国家的不同而相异。在很多情况下,通过语言假设主要国家的规范是合理的(如果没有指定国家);例如,如果指定了日本语,则可使用日本通用的日期格式。然而,如果是根据国家而设置的重要功能(例如货币),则必须给用户一个机会来修正该假设。
  
  在许多情况下,web应用程序是由若干组件组合而来的,这些组件可能已经本地化为不同的语言。一个特别值得一提的组件是Java运行环境,它在一些地区敏感区域可能具备支持超过40种语言中的100种区域设置的功能(例如日期格式),远远超出了典型的web应用程序。因此,应用程序开发者必须决定是否在整个应用程序中限制所支持语言的本地化功能,或者充分发挥每个组件的功能优势。第一种方法的优势在于用户可以看到的全部页面都使用同一语言,而第二种方法可能导致页面中存在不同的语言——其中一种语言出现在绝大多数文本中,而另一种则出现在例如日期的格式中。
  
  Java2StandardEditionPlatform中的本地化
  为了了解JSTL如何确定应用程序被哪些地区设置支持,我们来看看在基础的Java2StandardEdition平台中是如何进行本地化的。java.util软件包的核心主要有两种类:Locale和ResourceBundle。
  
  Locale对象只是用来确定地区设置的:它们结合了ISO639语言代码(例如,ja代表日文)和ISO3166国家代码(例如,IT代表意大利),还可能包含一个(非标准化的)变量字符串。注意,HTTP的地区标识符使用相同的ISO标准,所以对比通常比较容易。
  
  ResourceBundle对象是本地化对象的容器,形成成键/值对。一个基础资源束定义了一个基础束的名称、一套键以及默认值(通常是英文值,但不是必须的)。例如,一个简单的Messages资源束可能定义greeting-day键的默认值为Hello。其他的特定语言和国家束可以被定义,其名称由基础名称组成(通过后缀指示其语言、国家和变量)并提供已本地化的值。例如,德语Messages_de资源束可以给出GutenTag值(针对greeting-day键),而一个奥地利Messages_de_AT束可能用Servus值来覆盖该值。资源束可以作为Java类或简单的“属性”文本文件来执行。
  
  JavaServerPages应用程序的本地化方法
  要对基于JavaServerPages技术的应用程序进行本地化,方法通常有两个。第一个方法是使用国际化的页面,这些页面常可以通过自定义标记从资源束获得与特定地区设置相关的内容。如果页面需要保持复杂的结构并与所有地区设置同步,则通常会采取这种方法。第二种方法使用单独的特定地区设置页面以及分发到适当页面的servlet(取决于用户的地区选择)。如果页面包含的主要是文本或者地区设置间的结构截然不同时,则通常会采取这种方法。
  
  地区确定和JSTL中的本地化
  JSTL构建于J2SE工具之上,它可进行地区确定和本地化。使用任何一种JSP本地化方法(如上所述)均可以进行地区确定,而本地化功能的目的是为国际化的页面提供支持。
  
  JSTL对上述两种确定用户地区首选项的方法都提供支持。应用程序可以使用JSTL的<fmt:setLocale>操作,指定一个固定的地区(通常是用户从支持语言列表中所直接选择的)。一旦使用了该操作,指定的地区设置将应用于所有的地区敏感操作中。如果没有使用<fmt:setLocale>操作,地区敏感操作将会从地区选择列表中搜索第一种支持的地区设置,这些地区设置通常由Accept-Language报头提供。
  
  下面是一些您可以用于web应用程序开始页面的代码片断。这些代码片断可让用户非常轻松地选择他或她的地区设置。假设这些代码是locale-choice.jsp页面中的一部分:
  
  <%--Interpretuser'slocalechoice--%>
  <c:iftest="${param['locale']!=null}">
  <fmt:setLocalevalue="${param['locale']}"scope="session"/>
  </c:if>
  
  <%--Offerlocalechoicetouser--%>
  <ahref="locale-choice.jsp?locale=en-US">USA</a>-
  <ahref="locale-choice.jsp?locale=de-DE">Deutschland</a>-
  <ahref="locale-choice.jsp?locale=ja-JP">日本</a>
  
  <%--UseURLrewritingtoensurepropersessiontracking--%>
  <formmethod="get"action="<c:urlvalue='/locale-choice.jsp'/>">
  <inputtype=submitvalue="Stayinsession">
  </form>第一部份(此部分必须在生成的HTML页面任何内容之前)表示用户的地区选择,该选择作为一个请求参数显示在JSP页面上。如果定义了locale参数,则它将被用于进行会话的地区设置。
  
  第二部分(此部分是生成的HTML页面内容的一部分)为用户提供了返回同一页面的链接,但是根据选定的国家提供了locale参数设置。注意,在本地语言中已经给出国家的名称,所以即使页面的其他部分已经本地化为用户不能识别的语言,但是用户仍然可以容易地识别这些名称。例如,“日本”是“日本”的数字字符引用,即“日本”的日语单词。新版的浏览器如果装有日本字体,将会正确地转换这些文本;对于旧版的浏览器,使用图片则可能更合适一些。
  
  最后一部分显示如何使用<c:url>标记生成URL,此URL包含了一个会话ID,如果需要对该会话进行追踪的话(如果用户启用了cookies,则cookies将代替URL重写)。这将确保一旦选择了地区设置,该选择将应用于该web应用程序中的所有页面。
  
  如果从web应用程序本身的用户界面中选择了地区设置,然后使用<fmt:setLocale>进行设置,那么就可以假设该应用程序确实支持此地区设置。另一方面,如果没有使用<fmt:setLocale>并且JSTL必须从Accept-Language报头中的地区设置列表中找到一个支持的地区设置,那么情况会变得更复杂。
  
  要决定哪个地区设置是被支持的,JSTL将参考该应用程序所使用的资源束。有两种操作可用于访问资源束:<fmt:bundle>和<fmt:setBundle>。它们的基本功能是相同的:它们查询一个资源束并创建一个“本地化环境”,在这个“本地化环境”中包含了对该资源束和用于请求该资源束的地区设置的引用。
  
  <fmt:bundle>和<fmt:setBundle>操作所使用的资源束查询允许多次请求地区设置(这样它就可以处理由Accept-Language报头提供的列表),并使用由web应用程序定义的备用(fallback)地区设置。如果使用<fmt:setLocale>操作设置地区,那么<fmt:bundle>和<fmt:setBundle>操作将请求用于该地区设置的束,或者,如果不成功的话,将请求用于备用地区设置的束。如果没有使用<fmt:setLocale>,随后的操作将请求用于由Accept-Language报头提供的地区设置和备用地区设置,直到请求成功。在每种情况下,基本查询(查询束的基本名称和一个请求地区设置)将为请求地区设置本身搜索一个资源束,随后搜索更简单的地区设置(首先从请求地区设置中舍弃变量,然后舍弃国家组件)。如果全部的请求地区设置以及备用地区设置的查询都失败,那么将使用基础束。
  
  以下是一些例子。让我们假设某个应用程序拥有用于en、zh_CN、zh_TW、ja和ko的束。备用地区设置被设置为en。没有使用<fmt:setLocale>标记。下表显示最终本地化环境的束和地区设置(用于一些请求地区设置列表):
  
  被请求的地区设置
  结果束
  结果地区设置
  
  zh_SG、zh_CN
  zh_CN
  zh_CN
  
  zh、ja
  ja
  ja
  
  es_MX
  en
  en
  
  en_US
  en
  en_US
  
  ja、zh_CN
  ja
  ja
  
  
  ResourceBundle类的行家会注意到,JSTL操作所使用的查询策略与ResourceBundle所使用的查询策略是不同的。ResourceBundle使用的策略只接受一个请求地区设置,这不足以处理由Accept-Language报头所提供的地区设置列表,并且它会恢复Java运行环境的默认地区设置,此默认地区设置与web应用程序和其用户并不相关,使用它将导致不可移植性。
  
  那么,为什么查询资源束时存在两种不同的操作呢?它们的区别在于它们使用的方法:<fmt:bundle>标记提供了一个用于嵌套标记的环境,而<fmt:setBundle>操作将最终本地化环境存储在一个变量中,此变量可以在相同页面中被后继操作访问,并且可以被其他页面中的操作所访问(这取决于该变量的范围)。
  
  <fmt:message>操作是一种利用本地化环境的JSTL标记。它最简单的形式是,它从一个本地化环境的资源束中为一个指定的键获取一条信息并将该信息插入生成的页面中。下面例子显示了它的不同用法:
  
  <fmt:setBundlebasename="Errors"var="errorBundle"/>
  <fmt:bundlebasename="Messages">
  <%--Localizationcontextestablishedby<fmt:bundle>tag--%>
  <fmt:messagekey="greeting"/>
  <p>
  <%--Localizationcontextestablishedby<fmt:setBundle>tag--%>
  <fmt:messagekey="emptyField"bundle="${errorBundle}"/>
  </fmt:bundle>其次,为什么有一个请求地区设置与本地化环境相关联?这个地区设置是JSTL将格式化标记限制到应用程序所支持的语言范围内的方法,这样展现在读者面前的页面语言将完全统一。嵌套于<fmt:bundle>标记中的格式化操作使用该标记的本地化环境来确定它们应该使用的地区设置。例如,让我们观察下面的页面片断:
  
  <jsp:useBeanid="now"class="java.util.Date"/>
  <fmt:formatDatevalue="${now}"timeStyle="long"dateStyle="long"/>
  <p>
  <fmt:bundlebasename="Messages">
  <fmt:formatDatevalue="${now}"timeStyle="long"dateStyle="long"/>
  </fmt:bundle>如果HTTPAccept-Language地区设置是fr和en,并且基础的Java运行环境对这两种语言的日期格式都支持(但web应用程序的Messages束只存在于en),那么第一个日期采用法文格式,而第二个则采用英文格式。因此,页面设计者可以决定是使用统一的语言还是通过选择适当的标记嵌套来利用所有现有的本地化信息。
  
  最后,为什么本地化环境使用请求地区设置而不使用由资源束找到的地区设置?答案是,这样可以避免丢失重要的信息,某些格式标记可能需要这些信息。很多应用程序不能区分相同语言中不同变量之间的区别,而且只提供(例如)英文资源束,期望着这些文本在英国、澳大利亚和新加坡都能被同样理解。然而对于日期格式,国家是很关键的——对于英国读者来说,“2/6/02”表示“2002年6月2日”,但对于习惯美国规范的读者来说,则表示“2002年2月6日”。所以,在很多情况下,如果使用了请求地区设置(而不是资源束地区设置),则国家信息将会被保留。
  
  字符编码
  当前,我们使用两种截然不同的模块表示存储在计算机中或通过网络传输的文本:旧的字符编码模式专门用于较小的语言集合、国家和/或操作系统(包括如ISO8859系列、Windows代码页和EUC编码);而新的基于Unicode编码的模式能够(至少理论上能够)表示所有的语言并可以在任何地方使用。
  
  旧的模块具有很大的劣势:
  
  每种旧的字符编码方法通常只支持一个小的语言集合。例如,Shift-JIS支持日文和英文,但不支持其他的亚洲或欧洲语言。ISO8859-1支持一些西欧语言但不支持东欧语言。
  字符转换可能会带来意料之外的信息丢失。开发者通常选择ISO8859-1作为德语、法语和其它西欧语言的编码方法,然后会很惊讶地发现“€”字符(德国、法国和许多其他欧洲国家通用货币的标志)不被这种编码所支持。为了防止这种信息丢失,您必须使用Windows-1252、ISO8859-15或其他编码方法,这取决于浏览器的基础操作系统。
  当前版本的主要软件系统所包含的创建、分发和解释web内容都支持新的模块;它们通常将Unicode用于内部处理,或者至少知道怎么使用(用于web、基于Unicode编码的)UTF-8。基于Unicode的编码有着以下显著的优势:它们支持多语言页面并清晰区分地区设置(从字符编码处理)问题。同样,因为编码转换而带来的信息丢失的风险也很小,同时基于Unicode的编码与现在的服务器和客户端系统比较吻合。
  
  尽管如此,很多web开发者仍然不太愿意使用UTF-8。其中的原因可能包括对旧版本的浏览器支持不充分,或者缺少支持它的工具。
  
  JavaServerPages技术对新旧两种模块都支持。现在我们来看看字符编码问题所涉及的各种不同领域,并了解JSP技术和JSTL如何处理它们。
  
  处理源程序页编码
  JSP源文件的编码通常由可用的编辑工具决定,所以可能使用特定国家和操作系统的编码。字符编码与JSP运行环境(“容器”)之间的通讯方法有许多种,随着时间推移其中的机制和规则已不断改进。同时JSP源文件相应存在着两种语法:标准语法和基于XML的新语法。
  
  在检测字符编码时,JSP2.0规范将在这两种语法中进行辨别。对于采用XML语法的文件,编码将被检测为采用XML规范;这意味着UTF-8或UTF-16为默认的编码,而其他的编码必须在文件开始处的XML声明中予以说明。对于采用标准语法的文件,容器将考虑两种主要的信息来源:首先它们访问应用程序的配置描述符,查询一个page-encoding元素,该元素位于jsp-property-group(其URL格式与文件相匹配);然后在此页中查询pageEncoding属性。如果两者都没有,容器也会寻找contentType属性中的charset(参阅下一部分“处理Web页面编码”),或使用ISO8859-1作为最终的备用选择。
  
  以下是基于JSP2.0的应用程序的一些简单建议:对于采用XML语法的文件,确保没有使用UTF-8或UTF-16编码的文件能够正确识别它们的字符编码。对于采用标准语法的文件,如果您对所有源文件使用UTF-8,则请在配置描述符中只使用一个元素page-encoding来阐述它。如果您使用特定地区设置编码,则根据该地区设置来组织或命名您的文件,并使用page-encoding元素来描述它们的关系。例如,如果全部的韩文文件以EUC-KR编码并保存在/ko/KRweb的应用程序的子目录中,请使用以下语句:
  
  <jsp-property-group>
  <url-pattern>/ko/KR/*</url-pattern>
  <page-encoding>EUC-KR</page-encoding>
  </jsp-property-group>如果应用程序中的源文件不能以这种方式组织,则为每个源文件添加pageEncoding属性。不过请切记,此属性必须能够在文件的开始处找到并且只能用于标识ASCII扩展码的字符编码。后一个限制考虑到了UTF-8和许多旧的字符编码,但没考虑UTF-16或基于EBCDIC的编码。不建议根据contentType属性中的charset值来标识源程序页编码;这个值应只用于标识web页面编码(参见下一部分)。
  
  关于源文件字符编码,JSP1.2规范没有清楚地区分使用标准语法的文件和使用XML语法的文件。它也没有提供识别配置描述符中的字符编码的方法。为确保正确检测字符编码,设计用于JSP1.2容器的应用程序应总是识别每个使用pageEncoding属性的源文件中的字符编码。
  
  JSTL定义了一个<c:import>操作,该操作允许包含由URL指定到JSP生成的页面的外部数据。该操作允许字符编码规范,如果外部数据没有指定它本身的编码时会使用此规范。
  
  处理Web页面编码
  web应用程序必须选择生成的web页中使用的字符编码(该编码被称为“反应字符编码”),它基于目标浏览器的性能、页面内容的编写系统和语言以及可能的浏览器主机的操作系统。根据HTTP规范,字符编码在Content-Type实体报头的charset参数中被指定。
  
  如果所有目标浏览器都支持UTF-8,一般来说最好使用这种编码,这样就可以支持多语言文档并避免字符转换带来的信息丢失。
  
  如果不能使用UTF-8,必须小心谨慎地使用应用程序将字符编码与使用的语言相匹配,包括一些特殊字符。为防止出现错误,可能需要在整个页面里使用同一种语言,如本文开始部分“地区确定和本地化”中所述。同样,也有必要避免使用“€”字符。
  
  Web应用程序可以直接指定一个页面的字符编码,也可以让JSP技术根据地区设置信息间接决定。
  
  通过页面的contentType属性的显式规范最为简便,该属性可让应用程序连同生成页面的内容类型一起来指定字符编码。如果应用程序在处理请求时需要设置字符编码,则它需要使用一个自定义操作或一些Java代码来调用javax.servlet.ServletResponse.setContentType方法或新的(在Servlet2.4中)javax.servlet.ServletResponse.setCharacterEncoding方法。
  间接地,每当字符编码创建一个本地化环境时,它们也是由JSTL格式化操作(包括<fmt:message>)以及<fmt:bundle>、<fmt:setBundle>和<fmt:setLocale>操作无条件地来决定。通过ServletResponse.setLocale方法,它们将本地化环境的地区设置或指定的地区设置映射到一个字符编码并根据页面的内容类型对其进行设置。Servlet2.4规范通过配置描述符中的locale-encoding-mapping-list元素为应用程序提供了一个控制映射的方法。如果应用程序没有提供此元素,或者当您使用基于旧的Servlet规范的容器时,那么从地区设置到字符编码的映射取决于该容器;典型的实现依赖于旧的字符编码。
  间接决定字符编码是可行的,只要旧的字符编码可以被接受,并且整个页面使用相同的语言而且避免出现常用字符编码所不支持的特殊字符。然而,若要利用UTF-8则要求使用显式规范。因为Servlet2.4规范使显式规范优先于隐式规范,所以将字符编码设置为contentType属性的一部分已足够——随后使用JSTL格式化操作不会影响字符的编码。不过,在早期版本的Servlet规范中,并不保证地区设置信息中的显式规范优先于隐式决定。如果需要与基于旧规范的容器兼容,您必须通过在显式字符编码规范和首次使用自定义操作之间调用ServletResponse.flushBuffer来冻结字符编码,这些自定义操作可能间接决定字符编码。
  
  处理请求参数编码
  JSP技术不仅能够生成web页面,而且还可以接收和解释与HTTP请求一起收到的参数——通常是来自某种表格的输入,这种表格属于前面生成的web页面的一部分。用于这些参数的字符编码并非在任何地方都被指定,但实际标准是浏览器使用的编码要与包含这些表格的网页使用的编码相同。
  
  这意味着web应用程序需要跟踪先前生成的网页的编码。一个常用的机制是把编码的名称存储到表格本身的一个隐藏域中,在下一个请求时解压缩为第一个参数,然后用它来解码出其他的参数。然而,JSP页面还可以使用会话管理来跟踪请求之间的信息。
  
  应用程序可以使用JSTL自定义操作<fmt:requestEncoding>来指定要编码的参数的编码方法。如果应用程序总是发送UTF-8编码的页面,那么可以简单指定这种编码为请求编码。否则,如果它将直接指定生成页面的编码,它应该将该编码作为会话信息的一部分进行跟踪并直接将其传递给<fmt:requestEncoding>操作。如果它依赖于字符编码的间接决定,则它会简单地使用<fmt:requestEncoding>操作而无需指定一种字符编码;间接决定生成页面的编码这一操作还会在会话中储存信息,<fmt:requestEncoding>可以检索和使用这些信息。
  
  格式化和解析
  以本地化的格式表示数据(如数字和日期)是任何类型地应用程序都要完成的常见任务,就如同用户提供的输入解释。不同语言和文化所使用的格式区别很大,所以如果开发者不依靠现有的库的话,那么这个工作就不会是一项简单的任务。
  
  幸运的是,确实存在这样的库。Java2StandardEdition(J2SE)平台提供了在java.text软件包中用于格式化和解析常用数据类型的类库,并且Sun已将这些类库本地化为100多种地区设置。
  
  JavaServerPages标准标记库提供了自定义操作,可将这些功能直接应用到JSP页面中。
  
  用于格式化和解析操作的地区确定
  您可以在预定义的本地化环境中对数字和日期使用格式化和解析的操作(例如,如果标记嵌套于一个<fmt:bundle>标记中),或者在这种环境以外进行操作。如果您在预定义的本地化环境中使用操作,则它们将使用此本地化环境的地区设置。否则,它们将决定<fmt:bundle>和<fmt:setBundle>操作(如前文所述)的,用于修改的资源束查询策略所使用的地区设置。主要的区别在于:与查找资源束不同,算法通过使用java.text.NumberFormat.getAvailableLocales方法(用于数字格式化和解析操作)或者java.text.DateFormat.getAvailableLocales方法(用于日期和时间格式化和分解操作)来决定受支持的地区设置。
  
  数字格式化和解析
  JSTL用于数字格式化和解析的自定义操作<fmt:formatNumber>和<fmt:parseNumber>基于J2SE类java.text.NumberFormat,用于处理简单的数字以及百分比和货币值。
  
  特别值得一提的是它们对货币格式化的支持。传统上,许多格式化库假设货币符号可以从地区设置中得出——例如,如果地区设置是中国,那么货币符号就是人民币(RMB)。在一个跨境交易的环境中,这并没有多大的意义。如果某个英国公司以英镑来计算价格,而web应用程序将价格显示为人民币(RMB)的形式,就会出现两个问题:第一,人民币的汇率比英镑低;其次,人民币换回英镑会比较困难。由于货币的选择属于商业上的决定,所以货币必须作为值的一部分而不是格式的一部分。
  
  因此,<fmt:formatNumber>操作可以让应用程序指定一个ISO4217货币代码或货币符号,它将覆盖本地化数字格式使用的默认货币。假设应用程序使用一个带有值和货币属性的价格bean,下面的页面语句片断可以对价格进行格式化:
  
  <fmt:formatNumbertype="currency"value="${price.value}"
  currencyCode="${price.currency}"/>如果JSP页面指定了一个货币代码,则底层的NumberFormat对象会尝试对指定的货币使用一个货币符号,该指定的货币已本地化为所处本地化环境的地区设置。例如,如果为美元指定货币代码USD,则它可能会使用符号“$”(如果地区设置是en_US),在其他可接受该货币符号的地区设置中将使用US$,或者如果本地化符号未知,则使用备用货币代码USD。
  
  日期和时间的格式化和解析
  用于日期和时间的格式化和解析的JSTL自定义操作<fmt:formatDate>和<fmt:parseDate>基于J2SE类java.text.DateFormat并用于处理不同的日期和时间表示方法。
  
  令人感兴趣的一点是显示的日期和时间不仅仅取决于一种指定地区设置的格式,还取决于时区信息。用户通常对服务器时区不感兴趣,但另一方面,要找出用户所在地的时区却并不简单。应用程序可以通过使用一些客户端的JavaScript代码来找出用户的当前时区与格林尼治标准时间的偏差,或让用户指定当前时区并将其作为用户信息的一部分。JSTL操作并没有解决这个问题,但它们提供了两个自定义操作,可以用来告知有关时区的日期和时间的格式化和解析:<fmt:timeZone>和<fmt:setTimeZone>。与<fmt:bundle>和<fmt:setBundle>一样,<fmt:timeZone>标记可为嵌套标记定义时区,而<fmt:setTimeZone>将时区储存在一个变量中以供后继操作使用。
  
  信息格式化
  <fmt:message>操作(前面已提及)不但能从一个资源束中获取一个字符串并将其插入至生成的页面中,而且它还可以执行参数替换并根据需要格式化参数。它基于java.text.MessageFormat类,因此该操作获取的字符串实际上是一个MessageFormat模式字符串。<fmt:param>操作提供了必要的自变量。
  
  例如,如果JSP页面包含了以下语句:
  
  <jsp:useBeanid="now"class="java.util.Date"/>
  <fmt:bundlebasename="Messages">
  <fmt:messagekey="greeting">
  <fmt:paramvalue="${now}"/>
  </fmt:message>
  </fmt:bundle>并且找到的资源束是德语,而且为greeting键提供了“Willkommen!Heuteistder{0,date,long}.”值,那么生成日期为(假设)2002年6月21日的页面内容将会是“Willkommen!Heuteistder21.Juni2002.”
  
  结论
  如本文所述,JavaServerPages技术(特别是JavaServerPages标准标记库)为您提供了一个开发多语言应用程序的坚实基础。您需要仔细考虑以下几个设计选择:如何确定用户的语言和地区设置首选项,如何构造您用于本地化的JSP页面,是否采用单一语言的页面或充分利用现有的地区设置支持,以及使用哪一种字符编码模块。JSP技术使您能够选择其中任意一种,这样您就可以将页面以最佳的方式展示给全世界的读者,而且最重要的是,以他们自己的语言来展示。
  
  参考书目
  R.Fieldingetal.:HypertextTransferProtocol--HTTP/1.1.RFC2616.TheInternetSociety,1999.
  
  DaveRaggettetal.(ed.):HTML4.01Specification.WorldWideWebConsortium,1999.
  
  TimBrayetal.(ed.):ExtensibleMarkupLanguage(XML)1.0(SecondEdition).WorldWideWebConsortium,2000.
  
  Java2Platform,StandardEdition,v1.4.2APISpecification.SunMicrosystems,2002.
  
  DannyCoward(ed.):JavaServletSpecification.Version2.3.SunMicrosystems,2001.
  
  DannyCoward,YutakaYoshida(ed.):JavaServletSpecification.Version2.4.SunMicrosystems,2003.
  
  EduardoPelegrlopart(ed.):JavaServerPagesSpecification.Version1.2.SunMicrosystems,2001.
  
  MarkRoth,EduardoPelegrlopart(ed.):JavaServerPagesSpecification.Version2.0.SunMicrosystems,2003.
  
  PierreDelisle(ed.):JavaServerPagesStandardTagLibrary.Version1.0.SunMicrosystems,2002.
  
  PierreDelisle(ed.):JavaServerPagesStandardTagLibrary.Version1.1.SunMicrosystems,2003.
  
  关于作者
  NorbertLindenberg是SunMicrosystems的JavaWebServices团队内JavaInternationalization技术主管。在加盟Sun之前,曾经供职于GeneralMagic和AppleComputer,参与过多个国际化项目。他毕业于德国的卡尔斯鲁厄大学,拥有计算机科学理科硕士学位。

分享到:
本文"使用 JavaServer Pages 技术开发多语言 Web 应用程序"由远航站长收集整理而来,仅供大家学习与参考使用。更多网站制作教程尽在远航站长站。
顶一下
(0)
0%
踩一下
(0)
0%
[点击 次] [返回上一页] [打印]
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
关于本站 - 联系我们 - 网站声明 - 友情连接- 网站地图 - 站点地图 - 返回顶部
Copyright © 2007-2013 www.yhzhan.com(远航站长). All Rights Reserved .
远航站长:为中小站长提供最佳的学习与交流平台,提供网页制作与网站编程等各类网站制作教程.
官方QQ:445490277 网站群:26680406 网站备案号:豫ICP备07500620号-4