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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4276061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 15:15:47  来源:igfitidea点击:

How to internationalize a Java web application?

javajspunicodeinternationalization

提问by IamIronMAN

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 hereand there.

我从谷歌了解到国际化是我可以让我的网络应用程序使用所有语言的过程。我想在国际化的过程中了解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?

我的主要目标是开发一个网络翻译应用程序(英语到阿拉伯语,反之亦然)。我想关注国际化。我希望在所有三种浏览器(即 FF、Chrome、IE)中运行我的网络应用程序进行翻译。我如何实现这一目标?

采纳答案by BalusC

In case of a basic JSP/Servlet webapplication, the basic approach would be using JSTLfmttaglibin 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 fileswhich are loaded by ResourceBundleAPI. This can however be customized so that you can load the key-value pairs from for example a database.

对于基本的 JSP/Servlet web 应用程序,基本方法是将JSTL fmttaglib资源包结合使用。资源包包含键值对,其中键是一个常量,对于所有语言都相同,而值因语言而异。资源包通常是由API加载的属性文件ResourceBundle。但是,这可以自定义,以便您可以从例如数据库加载键值对。

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

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



  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).

    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)

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

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

    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 _llpart should be the lowercase ISO 693-1language code. It is optional and only required whenever the _CCpart is present. The _CCpart should be the uppercase ISO 3166-1 Alpha-2country 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).


  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.xmlis declared conform the Servlet 2.5 specification, then just put jstl-1.2.jarin webapp's /WEB-INF/libfolder.


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

    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 beforethe <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_CCspecifier).

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

    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).

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

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

    text.properties(包含默认语言的键值对,通常是英文)

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

    text_nl.properties(包含荷兰语 ( nl) 键值对)

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

    text_es.properties(包含西班牙语 ( es) 键值对)

    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)。


  2. 如果还没有完成,请安装 JSTL。如果您在 Servlet 2.5 容器或更新版本(Tomcat 6.0 等)上运行并且您web.xml声明符合 Servlet 2.5 规范,那么只需将jstl-1.2.jar放在 webapp 的/WEB-INF/lib文件夹中。


  3. 创建以下示例 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">管理当前语言。如果语言是作为请求参数提供的(通过语言下拉菜单),那么它将被设置。否则,如果该语言之前已在会话中设置,则改为使用它。否则在请求标头中使用用户提供的语言环境。

    <fmt:setLocale>设置了资源包的语言环境。重要的是,这条线是之前<fmt:setBundle>

    <fmt:setBundle>通过其基本名称初始化资源包(即,完全限定的包名称,直到与没有唯一名称_ll_CC指定符)。

    所述<fmt:message>检索由指定捆密钥的消息值。

    <html lang="${language}">通知searchbots的页面是什么语言,这样就不会被标记为重复的内容(因此,有利于搜索引擎优化)。

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



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.exetool. See also this article sectionfor more detail.

但是,您需要记住,默认情况下使用 ISO-8859-1 字符编码读取属性文件。您需要通过 unicode 转义来转义它们。这可以使用 JDK 提供的native2ascii.exe工具来完成。有关更多详细信息,另请参阅本文部分

A theoretical alternative would be to supply a bundle with a custom Controlto load those files as UTF-8, but that's unfortunately not supported by the basic JSTL fmttaglib. 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.

理论上的替代方法是提供一个带有自定义的包以将Control这些文件加载​​为 UTF-8,但不幸的是,基本的 JSTLfmt标记库不支持这种方式。您需要借助Filter. 有 (MVC) 框架可以以更透明的方式处理此问题,例如 JSF,另请参阅本文

回答by Pawe? Dyda

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 dirattribute to htmlelement of your JSP web page and externalize it, so the value comes from properties file (just like with other elements or attributes):

除了 BalusC 所说的之外,您还必须注意方向性(因为英语是从左到右书写的,而阿拉伯语则相反)。最简单的方法是向JSP 网页的元素添加dir属性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.

此外,设置此类应用程序的样式几乎没有问题 - 您至少应该避免绝对定位。如果由于某种原因无法避免这种情况,您可以为每种(每种?)语言使用不同的样式表,或者做一些禁止的事情,即使用表格来管理布局。如果您想使用 div 元素,我建议使用具有“对称”左右样式属性(两者都具有相同值)的相对定位,因为这是切换方向性起作用的原因。

You could find more about Bi-Directional websites here.

您可以在此处找到有关双向网站的更多信息。

回答by Ronen Rabinovici

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

基于本教程,我在 GAE - Google 的 App Engine 上使用以下内容:

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.propertiescontains:

并添加名为:(app.properties默认)和app_fr.properties(对每种语言以此类推​​)的文件。这些文件中的每一个都应包含您需要的字符串,如下所示:key:value_in_language,例如app_fr.properties包含:

greeting=Bonjour!

app.propertiescontains:

app.properties包含:

greeting=Hello!

That's all

就这样