gpt4 book ai didi

java - Java Web应用程序i18n

转载 作者:行者123 更新时间:2023-12-04 05:04:53 26 4
gpt4 key购买 nike

我已经完成了使用2.3 Servlet规范将i18n引入J2EE Web应用程序的任务(相当艰巨)。该应用程序非常大,并且已经积极开发了8年以上。

因此,我想第一时间解决问题,因此可以限制我花时间浏览JSP,JavaScript文件,Servlet和其他地方,用消息包中的值替换硬编码的字符串。

这里没有使用任何框架。我该如何寻求对i18n的支持。请注意,我希望每个 View 有一个JSP,该 View 从一个或多个属性文件中加载文本,而对于每个受支持的语言环境,则不希望有一个不同的JSP。

我想我的主要问题是我是否可以在“后端”中的某个位置设置语言环境(即,从登录时的用户配置文件中读取语言环境,并将其存储在 session 中的值),然后期望JSP页面将能够从中正确加载指定的字符串。正确的属性文件(例如,当语言环境为法语时,则来自messages_fr.properties),而不是在每个JSP中添加逻辑以查找正确的语言环境。

有什么想法可以解决这个问题吗?

最佳答案

国际化应用程序时,有很多事情需要注意:

语言环境检测

您需要考虑的第一件事是检测最终用户的语言环境。根据您要支持的内容,这可能很简单,也可能有些复杂。

  • 如您所知,Web浏览器倾向于通过HTTP Accept-Language header 发送最终用户的首选语言。在Servlet中访问此信息可能就像调用request.getLocale()一样简单。如果您不打算支持任何花哨的Locale Detection workflow,则可以坚持使用此方法。
  • 如果您的应用程序中有用户配置文件,则可能要向其中添加“首选语言”和“首选格式设置区域设置”。在这种情况下,您需要在用户登录后切换区域设置。
  • 您可能要支持基于URL的语言切换(例如:http://deutsch.example.com/http://example.com?lang=de)。您需要根据URL信息设置有效的语言环境-可以通过多种方式(例如,URL过滤器)来完成此设置。
  • 您可能要支持语言切换(从下拉菜单中选择它,或进行其他操作),但是我不建议这样做(除非它与第3点结合使用)。

  • 如果您只想支持第一种方法,或者您不打算添加任何其他依赖项(例如Spring Framework),那么 JSTL 方法就足够了。

    在Spring框架 中,我们拥有很多不错的功能,您可以使用它们来检测Locale(例如CookieLocaleResolverAcceptHeaderLocaleResolverSessionLocaleResolverLocaleChangeInterceptor)以及外部化字符串和格式化消息(请参阅spring:message tab)。
    Spring Framework可以让您轻松地实现上述所有方案,这就是为什么我更喜欢它。

    字符串外部化

    这应该很容易,对吗?好吧,大多数情况是-只需使用适当的标签即可。您可能面临的唯一问题是外部化客户端(JavaScript)文本时。有几种可能的方法,但让我提及以下两种:
  • 让每个JSP编写翻译字符串(带有message标记)的数组,并只需在客户端代码中访问该数组即可。这是较简单的方法,但维护性较差-您实际上需要从有效页面(实际上是引用您的客户端脚本的页面)中写入有效字符串。我之前已经做过,并且相信我,这不是您在大型应用程序中想要做的事情(但这可能是小型应用程序的最佳解决方案)。
  • 从原理上讲,另一种方法听起来可能很困难,但实际上将来更容易处理。这个想法是将字符串集中在客户端(将它们移动到一些常见的JavaScript文件中)。之后,您将需要实现自己的Servlet,该Servlet将根据请求返回此脚本-应该转换其内容。您将无法在这里使用JSTL,您需要直接从Resource Bundles获取字符串。
    维护起来容易得多,因为您将有一个中心点来添加可翻译的字符串。

  • 串联

    我讨厌这样说,但是从Localizability的角度来看,连接确实很痛苦。它们很常见,大多数人都没有意识到。

    那么串联是什么呢?

    原则上,每个英语句子都需要翻译成目标语言。问题是,正确翻译的消息会多次使用与其英语对应词不同的词序(因此,英语“安全策略”被翻译成波兰语“Politykabezpieczeństwa” –“policy”是“polityka” –次序不同)。

    好的,但是它和软件有什么关系?

    在Web应用程序中,您可以像这样连接字符串:
    String securityPolicy = "Security " + "policy";

    或像这样:
    <p><span style="font-weight:bold">Security</span> policy</p>

    两者都会有问题。在第一种情况下,您将需要使用MessageFormat.format()方法并将字符串外部化为(例如)"Security {0}""policy",在后一种情况中,您将外部化整个段落的内容(p标签),包括 span标签。我知道这对翻译人员来说是痛苦的,但实际上没有更好的方法。
    有时,您必须在段落中使用动态内容-JSTL fmt:format标记也将在此处为您提供帮助(它在后端使用了MessageFormat)。

    布局

    在本地化的应用程序中,翻译后的字符串通常比英语长得多。结果看起来很丑。不知何故,您需要修复样式。再次有两种方法:
  • 通过调整常见样式来解决问题(并祈祷它不会破坏其他语言)。维护起来非常痛苦。
  • 实现CSS本地化机制。我正在谈论的机制应该提供默认的,独立于语言的CSS文件和每种语言覆盖。想法是为每种语言设置覆盖CSS文件,以便您可以按需调整布局(仅针对一种语言)。为此,默认CSS文件以及JSP页面的任何样式定义旁边均不得包含!important关键字。如果确实需要使用它,请将它们移至基于语言的en.css-这将允许其他语言对其进行修改。

  • 特定于文化的问题

    避免使用可能特定于西方文化的图形,颜色和声音。如果您确实需要它,请提供本地化方法。避免使用对方向敏感的图形(因为当您尝试本地化为阿拉伯语或希伯来语时会出现问题)。同样,不要假设整个世界都使用相同的数字(即阿拉伯语不是这样)。

    日期和时区

    至少可以说,在Java中按时间处理日期并非易事。如果您除了格里高利日历之外不支持其他功能,则可以坚持使用内置的日期和日历类。
    您可以使用JSTL fmt:timeZone,fmt:formatDate和fmt:parseDate在JSP中正确设置时区,格式和解析日期。

    我强烈建议像这样使用fmt:formatDate:
    <fmt:formatDate value="${someController.somedate}" 
    timeZone="${someController.detectedTimeZone}"
    dateStyle="default"
    timeStyle="default" />

    将日期和时间隐藏到有效(最终用户)时区很重要。将其转换为易于理解的格式也很重要-这就是为什么我建议使用默认格式样式的原因。
    顺便提一句。时区检测并非易事,因为Web浏览器发送任何内容都不是一件好事。相反,您可以将“首选时区”字段添加到“用户”偏好设置中(如果有的话),也可以通过客户端脚本从Web浏览器获取当前时区偏移量(请参见Date object's methods)

    数字和货币

    数字和货币应转换为本地格式。可以通过与格式化日期类似的方式来完成此操作(解析也可以类似地完成):
    <fmt:formatNumber value="1.21" type="currency"/> 

    复合消息

    您已经被警告不要连接字符串。相反,您可能会使用MessgageFormat。但是,我必须指出,您应该最大程度地减少使用复合消息。那只是因为目标语法规则通常有很大不同,所以翻译者可能不仅需要重新排列句子(这将通过使用占位符和MessageFormat.format()来解决),而且还需要根据替换的内容以不同的方式翻译整个句子。让我给你举一些例子:
    // Multiple plural forms
    English: 4 viruses found.
    Polish: Znaleziono 4 wirusy. **OR** Znaleziono 5 wirusów.

    // Conjugation
    English: Program encountered incorrect character | Application encountered incorrect character.
    Polish: Program napotkał nieznaną literę | Aplikacja napotkała nieznaną literę.

    字符编码

    如果您打算本地化为不支持ISO 8859-1代码页的语言,则需要支持Unicode-最好的方法是将页面编码设置为UTF-8。我见过有人这样做:
    <%@ page contentType="text/html; charset=UTF-8" %>

    我必须警告您:这不够。您实际上需要此声明:
    <%@page pageEncoding="UTF-8" %>

    同样,为了安全起见,您仍然需要在页面标题中声明编码:
    <META http-equiv="Content-Type" content="text/html;charset=UTF-8"> 

    我给您的 list 并不详尽,但这是一个很好的起点。祝你好运 :)

    关于java - Java Web应用程序i18n,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6448451/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com