如何国际化Java web应用程序?

时间:2022-05-11 22:49:17

I learnt from Google that Internationalization is the process by which I can make my web application to use all languages. I want to understand Unicode for the process of internationalization, so I learnt about Unicode from here and there.

我从谷歌中了解到,国际化是使我的web应用程序使用所有语言的过程。我想了解国际化过程的Unicode,因此我从这里和那里了解了Unicode。

I am able to understand about Unicode that how a charset set in encoded to bytes and again bytes decoded to charset. But I don't know how to move forward further. I want to learn how to compare strings and I need to know how to implement internationalization in my web application. Any Suggestions Please? Please guide me.

我能够理解Unicode,即字符集是如何编码成字节的,而字节又是如何解码成字符集的。但我不知道如何继续前进。我想学习如何比较字符串,我需要知道如何在我的web应用程序中实现国际化。有什么建议吗?请指导我。

My Objective:

我的目标:

My main objective is to develop a Web Application for Translation (English to Arabic & vice versa). I want to follow Internationalization. I wish to run my web Application for translation in all the three browsers namely FF, Chrome, IE. How do I achieve this?

我的主要目标是开发一个用于翻译的Web应用程序(英语到阿拉伯语,反之亦然)。我想跟随国际化。我希望在所有三个浏览器中运行我的web应用程序,即FF, Chrome, IE。我该如何做到这一点?

3 个解决方案

#1


208  

In case of a basic JSP/Servlet webapplication, the basic approach would be using JSTL fmt taglib in combination with resource bundles. Resource bundles contain key-value pairs where the key is a constant which is the same for all languages and the value differs per language. Resource bundles are usually properties files which are loaded by ResourceBundle API. This can however be customized so that you can load the key-value pairs from for example a database.

对于基本的JSP/Servlet web应用程序,基本的方法是将JSTL fmt taglib与资源包结合使用。资源包包含键-值对,其中键是常量,对于所有语言都是相同的,每种语言的值都不同。资源包通常是ResourceBundle API加载的属性文件。但是,这可以定制,这样您就可以从数据库中加载键值对。

Here's an example how to internationalize the login form of your webapplication with properties file based resource bundles.

下面是一个如何使用基于属性文件的资源包国际化webapplication的登录表单的示例。


  1. Create the following files and put them in some package, e.g. com.example.i18n (in case of Maven, put them in the package structure inside src/main/resources).

    创建以下文件,并将它们放在某个包中,例如com.example。i18n(在Maven中,将它们放入src/main/resources中的包结构中)。

    text.properties (contains key-value pairs in the default language, usually English)

    文本。属性(默认语言中包含键值对,通常为英语)

    login.label.username = Username
    login.label.password = Password
    login.button.submit = Sign in
    

    text_nl.properties (contains Dutch (nl) key-value pairs)

    text_nl。属性(包含荷兰语(nl)键-值对)

    login.label.username = Gebruikersnaam
    login.label.password = Wachtwoord
    login.button.submit = Inloggen
    

    text_es.properties (contains Spanish (es) key-value pairs)

    text_es。属性(包含西班牙语(es)键-值对)

    login.label.username = Nombre de usuario
    login.label.password = Contraseña
    login.button.submit = Acceder
    

    The resource bundle filename should adhere the following pattern name_ll_CC.properties. The _ll part should be the lowercase ISO 693-1 language code. It is optional and only required whenever the _CC part is present. The _CC part should be the uppercase ISO 3166-1 Alpha-2 country code. It is optional and often only used to distinguish between country-specific language dialects, like American English (_en_US) and British English (_en_GB).

    资源包文件名应该遵循以下模式name_ll_CC.properties。_ll部分应该是小写的ISO 693-1语言代码。它是可选的,只有当_CC部分出现时才需要。_CC部分应该是大写的ISO 3166-1 Alpha-2国家代码。它是可选的,通常只用于区分特定国家的语言方言,如美式英语(_en_US)和英式英语(_en_GB)。


  2. If not done yet, install JSTL. If you're running on a Servlet 2.5 container or newer (Tomcat 6.0 and so on) and your web.xml is declared conform the Servlet 2.5 specification, then just put jstl-1.2.jar in webapp's /WEB-INF/lib folder.

    如果尚未完成,请安装JSTL。如果您正在Servlet 2.5容器或更新(Tomcat 6.0等)和web上运行。声明xml符合Servlet 2.5规范,然后放入jstl-1.2。jar在webapp的/WEB-INF/lib文件夹中。


  3. Create the following example JSP file and put it in web content folder.

    创建以下示例JSP文件并将其放入web内容文件夹。

    login.jsp

    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>
    

    The <c:set var="language"> manages the current language. If the language was supplied as request parameter (by language dropdown), then it will be set. Else if the language was already previously set in the session, then stick to it instead. Else use the user supplied locale in the request header.

    管理当前语言。如果语言是作为请求参数(通过语言下拉)提供的,那么它将被设置。否则,在请求头中使用用户提供的语言环境。

    The <fmt:setLocale> sets the locale for resource bundle. It's important that this line is before the <fmt:setBundle>.

    为资源包设置语言环境。这一行在 之前是很重要的。

    The <fmt:setBundle> initializes the resource bundle by its base name (that is, the full qualified package name until with the sole name without the _ll_CC specifier).

    通过它的基名(即完整的限定包名,直到唯一的名称没有_ll_CC说明符)初始化资源包。

    The <fmt:message> retrieves the message value by the specified bundle key.

    消息>通过指定的bundle键检索消息值。

    The <html lang="${language}"> informs the searchbots what language the page is in so that it won't be marked as duplicate content (thus, good for SEO).

    通知searchbots这个页面是什么语言,这样它就不会被标记为重复的内容(因此,对SEO来说很好)。

    The language dropdown will immediately submit by JavaScript when another language is chosen and the page will be refreshed with the newly chosen language.

    当选择另一种语言时,语言下拉菜单将立即由JavaScript提交,并使用新选择的语言刷新页面。


You however need to keep in mind that properties files are by default read using ISO-8859-1 character encoding. You would need to escape them by unicode escapes. This can be done using the JDK-supplied native2ascii.exe tool. See also this article section for more detail.

但是,您需要记住,属性文件是使用ISO-8859-1字符编码默认读取的。您需要通过unicode转义符来转义它们。这可以使用jdk提供的native2ascii实现。exe工具。有关更多细节,请参见本文部分。

A theoretical alternative would be to supply a bundle with a custom Control to load those files as UTF-8, but that's unfortunately not supported by the basic JSTL fmt taglib. You would need to manage it all yourself with help of a Filter. There are (MVC) frameworks which can handle this in a more transparent manner, like JSF, see also this article.

一个理论上的替代方案是提供一个带有自定义控件的包,以将这些文件作为UTF-8加载,但不幸的是,基本的JSTL fmt taglib并不支持这种方法。在过滤器的帮助下,您需要自己管理它。有一些(MVC)框架可以以更透明的方式处理这些问题,比如JSF,请参阅本文。

#2


24  

In addition to what BalusC said, you have to take care about directionality (since English is written Left-To-Right and Arabic the other way round). The easiest way would be to add dir attribute to html element of your JSP web page and externalize it, so the value comes from properties file (just like with other elements or attributes):

除了BalusC所说的之外,您还必须注意方向(因为英语是从左到右写,阿拉伯语反过来写)。最简单的方法是将dir属性添加到JSP web页面的html元素中并将其具体化,因此该值来自属性文件(与其他元素或属性相同):

<html dir="${direction}">
...
</html>

Also, there are few issues with styling such application - you should to say the least avoid absolute positioning. If you cannot avoid that for some reason, you could either use different stylesheets per (each?) language or do something that is verboten, that is use tables for managing layout. If you want to use div elements, I'd suggest to use relative positioning with "symmetric" left and right style attributes (both having the same value), since this is what makes switching directionality work.

此外,在样式化应用程序方面也没有什么问题——您应该说至少要避免绝对定位。如果由于某种原因无法避免这种情况,您可以使用不同的样式表(每一种)语言或做一些verboten,即使用表来管理布局。如果您想使用div元素,我建议使用带有“对称”左右样式属性的相对定位(两者具有相同的值),因为这是切换方向性工作的原因。

You could find more about Bi-Directional websites here.

你可以在这里找到更多关于双向网站的信息。

#3


1  

based on this tutorial, I am using the following on GAE - Google's App Engine:

基于本教程,我正在使用GAE -谷歌的应用程序引擎:

A jsp file as follows:

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>

And adding the files named: app.properties (default) and app_fr.properties (and so on for every language). Each of these files should contain the strings you need as follows: key:value_in_language, e.g. app_fr.properties contains:

并添加名为:app.properties(默认)和app_fr的文件。属性(每种语言都是如此)。每个文件都应该包含如下所需的字符串:key:value_in_language,例如app_fr。属性包含:

greeting=Bonjour!

app.properties contains:

app.properties包含:

greeting=Hello!

That's all

这是所有

#1


208  

In case of a basic JSP/Servlet webapplication, the basic approach would be using JSTL fmt taglib in combination with resource bundles. Resource bundles contain key-value pairs where the key is a constant which is the same for all languages and the value differs per language. Resource bundles are usually properties files which are loaded by ResourceBundle API. This can however be customized so that you can load the key-value pairs from for example a database.

对于基本的JSP/Servlet web应用程序,基本的方法是将JSTL fmt taglib与资源包结合使用。资源包包含键-值对,其中键是常量,对于所有语言都是相同的,每种语言的值都不同。资源包通常是ResourceBundle API加载的属性文件。但是,这可以定制,这样您就可以从数据库中加载键值对。

Here's an example how to internationalize the login form of your webapplication with properties file based resource bundles.

下面是一个如何使用基于属性文件的资源包国际化webapplication的登录表单的示例。


  1. Create the following files and put them in some package, e.g. com.example.i18n (in case of Maven, put them in the package structure inside src/main/resources).

    创建以下文件,并将它们放在某个包中,例如com.example。i18n(在Maven中,将它们放入src/main/resources中的包结构中)。

    text.properties (contains key-value pairs in the default language, usually English)

    文本。属性(默认语言中包含键值对,通常为英语)

    login.label.username = Username
    login.label.password = Password
    login.button.submit = Sign in
    

    text_nl.properties (contains Dutch (nl) key-value pairs)

    text_nl。属性(包含荷兰语(nl)键-值对)

    login.label.username = Gebruikersnaam
    login.label.password = Wachtwoord
    login.button.submit = Inloggen
    

    text_es.properties (contains Spanish (es) key-value pairs)

    text_es。属性(包含西班牙语(es)键-值对)

    login.label.username = Nombre de usuario
    login.label.password = Contraseña
    login.button.submit = Acceder
    

    The resource bundle filename should adhere the following pattern name_ll_CC.properties. The _ll part should be the lowercase ISO 693-1 language code. It is optional and only required whenever the _CC part is present. The _CC part should be the uppercase ISO 3166-1 Alpha-2 country code. It is optional and often only used to distinguish between country-specific language dialects, like American English (_en_US) and British English (_en_GB).

    资源包文件名应该遵循以下模式name_ll_CC.properties。_ll部分应该是小写的ISO 693-1语言代码。它是可选的,只有当_CC部分出现时才需要。_CC部分应该是大写的ISO 3166-1 Alpha-2国家代码。它是可选的,通常只用于区分特定国家的语言方言,如美式英语(_en_US)和英式英语(_en_GB)。


  2. If not done yet, install JSTL. If you're running on a Servlet 2.5 container or newer (Tomcat 6.0 and so on) and your web.xml is declared conform the Servlet 2.5 specification, then just put jstl-1.2.jar in webapp's /WEB-INF/lib folder.

    如果尚未完成,请安装JSTL。如果您正在Servlet 2.5容器或更新(Tomcat 6.0等)和web上运行。声明xml符合Servlet 2.5规范,然后放入jstl-1.2。jar在webapp的/WEB-INF/lib文件夹中。


  3. Create the following example JSP file and put it in web content folder.

    创建以下示例JSP文件并将其放入web内容文件夹。

    login.jsp

    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>
    

    The <c:set var="language"> manages the current language. If the language was supplied as request parameter (by language dropdown), then it will be set. Else if the language was already previously set in the session, then stick to it instead. Else use the user supplied locale in the request header.

    管理当前语言。如果语言是作为请求参数(通过语言下拉)提供的,那么它将被设置。否则,在请求头中使用用户提供的语言环境。

    The <fmt:setLocale> sets the locale for resource bundle. It's important that this line is before the <fmt:setBundle>.

    为资源包设置语言环境。这一行在 之前是很重要的。

    The <fmt:setBundle> initializes the resource bundle by its base name (that is, the full qualified package name until with the sole name without the _ll_CC specifier).

    通过它的基名(即完整的限定包名,直到唯一的名称没有_ll_CC说明符)初始化资源包。

    The <fmt:message> retrieves the message value by the specified bundle key.

    消息>通过指定的bundle键检索消息值。

    The <html lang="${language}"> informs the searchbots what language the page is in so that it won't be marked as duplicate content (thus, good for SEO).

    通知searchbots这个页面是什么语言,这样它就不会被标记为重复的内容(因此,对SEO来说很好)。

    The language dropdown will immediately submit by JavaScript when another language is chosen and the page will be refreshed with the newly chosen language.

    当选择另一种语言时,语言下拉菜单将立即由JavaScript提交,并使用新选择的语言刷新页面。


You however need to keep in mind that properties files are by default read using ISO-8859-1 character encoding. You would need to escape them by unicode escapes. This can be done using the JDK-supplied native2ascii.exe tool. See also this article section for more detail.

但是,您需要记住,属性文件是使用ISO-8859-1字符编码默认读取的。您需要通过unicode转义符来转义它们。这可以使用jdk提供的native2ascii实现。exe工具。有关更多细节,请参见本文部分。

A theoretical alternative would be to supply a bundle with a custom Control to load those files as UTF-8, but that's unfortunately not supported by the basic JSTL fmt taglib. You would need to manage it all yourself with help of a Filter. There are (MVC) frameworks which can handle this in a more transparent manner, like JSF, see also this article.

一个理论上的替代方案是提供一个带有自定义控件的包,以将这些文件作为UTF-8加载,但不幸的是,基本的JSTL fmt taglib并不支持这种方法。在过滤器的帮助下,您需要自己管理它。有一些(MVC)框架可以以更透明的方式处理这些问题,比如JSF,请参阅本文。

#2


24  

In addition to what BalusC said, you have to take care about directionality (since English is written Left-To-Right and Arabic the other way round). The easiest way would be to add dir attribute to html element of your JSP web page and externalize it, so the value comes from properties file (just like with other elements or attributes):

除了BalusC所说的之外,您还必须注意方向(因为英语是从左到右写,阿拉伯语反过来写)。最简单的方法是将dir属性添加到JSP web页面的html元素中并将其具体化,因此该值来自属性文件(与其他元素或属性相同):

<html dir="${direction}">
...
</html>

Also, there are few issues with styling such application - you should to say the least avoid absolute positioning. If you cannot avoid that for some reason, you could either use different stylesheets per (each?) language or do something that is verboten, that is use tables for managing layout. If you want to use div elements, I'd suggest to use relative positioning with "symmetric" left and right style attributes (both having the same value), since this is what makes switching directionality work.

此外,在样式化应用程序方面也没有什么问题——您应该说至少要避免绝对定位。如果由于某种原因无法避免这种情况,您可以使用不同的样式表(每一种)语言或做一些verboten,即使用表来管理布局。如果您想使用div元素,我建议使用带有“对称”左右样式属性的相对定位(两者具有相同的值),因为这是切换方向性工作的原因。

You could find more about Bi-Directional websites here.

你可以在这里找到更多关于双向网站的信息。

#3


1  

based on this tutorial, I am using the following on GAE - Google's App Engine:

基于本教程,我正在使用GAE -谷歌的应用程序引擎:

A jsp file as follows:

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>

And adding the files named: app.properties (default) and app_fr.properties (and so on for every language). Each of these files should contain the strings you need as follows: key:value_in_language, e.g. app_fr.properties contains:

并添加名为:app.properties(默认)和app_fr的文件。属性(每种语言都是如此)。每个文件都应该包含如下所需的字符串:key:value_in_language,例如app_fr。属性包含:

greeting=Bonjour!

app.properties contains:

app.properties包含:

greeting=Hello!

That's all

这是所有