如何国际化Java Web应用程序?
我从Google那里了解到,国际化是我可以使我的Web应用程序使用所有语言的过程。 我想了解Unicode的国际化进程,所以我从各处学习了Unicode。
我能够了解Unicode如何将字符集编码为字节,再将字节解码为字符集。 但是我不知道如何继续前进。 我想学习如何比较string,我需要知道如何在我的web应用程序中实现国际化。 有什么build议吗? 请指导我
我的目标:
我的主要目标是开发一个用于翻译的Web应用程序(英语到阿拉伯语,反之亦然)。 我想遵循国际化。 我希望在所有三种浏览器(FF,Chrome,IE)中运行我的Web应用程序进行翻译。 我如何做到这一点?
对于基本的JSP / Servlet Web应用程序,基本方法是将JSTL fmt
taglib与资源包结合使用。 资源包包含键值对,其中键是常量,对于所有语言都是相同的,并且每个语言的值不同。 资源包通常是由ResourceBundle
API加载的属性文件 。 这可以自定义,以便您可以从例如数据库加载键值对。
下面是一个示例,介绍如何使用基于属性文件的资源包将您的Web应用程序的login表单国际化。
-
创build下面的文件,并把它们放在一些包中,例如
com.example.i18n
(Maven的情况下,把它们放在src/main/resources
的包结构中)。text.properties
(包含默认语言的键值对,通常是英文)login.label.username =用户名 login.label.password =密码 login.button.submit =login
text_nl.properties
(包含荷兰语(nl
)键值对)login.label.username = Gebruikersnaam login.label.password = Wachtwoord login.button.submit =login
text_es.properties
(包含西class牙语键值对)login.label.username = Nombre de usuario login.label.password =Contraseña login.button.submit = Acceder
资源包文件名应该遵循以下模式
name_ll_CC.properties
。_ll
部分应该是小写的ISO 693-1语言代码。 这是可选的,只有_CC
部分存在时才需要。_CC
部分应该是大写的ISO 3166-1 Alpha-2国家代码。 它是可选的,通常只用于区分国家特定的语言方言,如美国英语 (_en_US
)和英国英语 (_en_GB
)。
-
如果尚未安装,请安装JSTL。 如果您运行的是Servlet 2.5容器或更新版本(Tomcat 6.0等),并且声明的
web.xml
符合Servlet 2.5规范,那么只需将jstl-1.2.jar放入webapp的/WEB-INF/lib
文件夹即可。
-
创build以下示例JSP文件并将其放入Web内容文件夹中。
login.jsp
<%@ page pageEncoding="UTF-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <c:set var="language" value="${not empty param.language ? param.language : not empty language ? language : pageContext.request.locale}" scope="session" /> <fmt:setLocale value="${language}" /> <fmt:setBundle basename="com.example.i18n.text" /> <!DOCTYPE html> <html lang="${language}"> <head> <title>JSP/JSTL i18n demo</title> </head> <body> <form> <select id="language" name="language" onchange="submit()"> <option value="en" ${language == 'en' ? 'selected' : ''}>English</option> <option value="nl" ${language == 'nl' ? 'selected' : ''}>Nederlands</option> <option value="es" ${language == 'es' ? 'selected' : ''}>Español</option> </select> </form> <form method="post"> <label for="username"><fmt:message key="login.label.username" />:</label> <input type="text" id="username" name="username"> <br> <label for="password"><fmt:message key="login.label.password" />:</label> <input type="password" id="password" name="password"> <br> <fmt:message key="login.button.submit" var="buttonValue" /> <input type="submit" name="submit" value="${buttonValue}"> </form> </body> </html>
<c:set var="language">
pipe理当前的语言。 如果语言是作为请求参数提供的(通过语言下拉菜单),那么它将被设置。 否则,如果语言已经在会话中被预先设置,那么请坚持使用它。 否则在请求头中使用用户提供的区域设置。<fmt:setLocale>
设置资源包的语言环境。 这一行在<fmt:setBundle>
之前是很重要的。<fmt:setBundle>
通过其基本名称(即完全限定的包名称,直到没有_ll_CC
说明符的唯一名称)初始化资源包。<fmt:message>
通过指定的捆绑键检索消息值。<html lang="${language}">
通知searchbots这个网页是什么语言,这样它就不会被标记为重复的内容(因此对于SEO来说很好)。当select另一种语言时,语言下拉菜单将立即通过JavaScript提交,页面将用新select的语言刷新。
不过需要注意的是,默认情况下,属性文件是使用ISO-8859-1字符编码读取的。 你需要通过unicode escapes来逃脱它们。 这可以使用JDK提供的native2ascii.exe
工具来完成。 有关更多详细信息,另请参阅本文章节 。
一个理论上的替代方法是提供一个自定义的Control
包来加载这些文件为UTF-8,但不幸的是不支持基本的JSTL fmt
taglib。 你需要在Filter
帮助下自己pipe理它。 有(MVC)框架,可以处理这个更透明的方式,如JSF,也请参阅这篇文章 。
除了BalusC所说的,你必须注意方向性(因为英语是从左到右写的,而阿拉伯语是相反的)。 最简单的方法是将dir
属性添加到JSP网页的html
元素并将其外部化,所以值来自属性文件(就像其他元素或属性一样):
<html dir="${direction}"> ... </html>
此外,这样的应用程序样式的问题很less – 你应该说至less避免绝对定位。 如果由于某种原因无法避免这种情况,则可以使用不同的样式表(每个?),也可以使用不同的样式表来进行布局pipe理。 如果你想使用div元素,我build议使用“对称”左右风格属性(都具有相同的值)的相对定位,因为这是什么使得切换方向性工作。
您可以在这里find更多关于双向网站的信息 。
基于本教程 ,我在GAE上使用了以下内容 – Google App Engine:
一个jsp文件如下:
<%@ page import="java.io.* %> <% String lang = "fr"; //Assign the correct language either by page or user-selected or browser language etc. ResourceBundle RB = ResourceBundle.getBundle("app", new Locale(lang)); %> <!DOCTYPE html> <%@ page contentType="text/html;charset=UTF-8" language="java"%> <head> </head> <body> <p> <%= RB.getString("greeting") %> </p> </body>
并添加名为: app.properties
(默认)和app_fr.properties
(等等每个语言)的文件。 这些文件中的每一个都应该包含您需要的string,如下所示:key:value_in_language,例如app_fr.properties
包含:
greeting=Bonjour!
app.properties
包含:
greeting=Hello!
就这样