NRa*_*Raf 8 java jsp internationalization
我已经获得了使用2.3 servlet规范将i18n引入J2EE Web应用程序的(相当艰巨的)任务.该应用程序非常庞大,已经积极开发了8年多.
因此,我希望第一次就把事情做好,这样我就可以限制我需要在JSP,JavaScript文件,servlet和其他任何地方乱写的时间,用消息包中的值替换硬编码的字符串.
这里没有使用框架.我怎样才能支持i18n.请注意,我希望每个视图都有一个JSP,它可以从(a)属性文件加载文本,而不是为每个支持的语言环境加载不同的JSP.
我想我的主要问题是我是否可以在'后端'中的某处设置区域设置(即在登录时从用户配置文件中读取区域设置并在会话中存储值),然后期望JSP页面能够正确加载指定的字符串.正确的属性文件(即,当语言环境为法语时,来自messages_fr.properties),而不是添加逻辑以在每个JSP中查找正确的语言环境.
我有什么想法可以解决这个问题吗?
Paw*_*yda 19
在国际化应用程序时需要注意很多事情:
区域设置检测
您需要考虑的第一件事是检测最终用户的区域设置.根据您想要支持的内容,它可能很容易或有点复杂.
request.getLocale().如果您不打算支持任何花哨的Locale Detection工作流程,您可能会坚持使用此方法.如果您只想支持第一种方法,或者您不打算添加任何其他依赖项(如Spring Framework),那么 JSTL方法就足够了.
当我们使用Spring Framework时,它有很多不错的功能,您可以使用它们来检测Locale(如CookieLocaleResolver,AcceptHeaderLocaleResolver,SessionLocaleResolver和LocaleChangeInterceptor)以及外部化字符串和格式化消息(请参阅spring:message选项卡).
Spring Framework允许您轻松实现上面的所有场景,这就是我喜欢它的原因.
字符串外化
这应该是容易的,对吧?好吧,主要是 - 只需使用适当的标签.您可能面临的唯一问题是外部化客户端(JavaScript)文本.有几种可能的方法,但我要提到这两种方法:
级联
我讨厌这样说,但从Localizability的角度来看,连接真的很痛苦.它们很常见,大多数人都没有意识到这一点.
那么什么是串联呢?
原则上,每个英语句子都需要翻译成目标语言.问题是,正确翻译的消息使用不同的单词顺序发生了很多次,因为英语"安全政策"被翻译成波兰语"Politykabezpieczeństwa" - "政策"是"polityka" - 顺序不同).
好的,但它与软件有什么关系?
在Web应用程序中,您可以像这样连接字符串:
String securityPolicy = "Security " + "policy";
Run Code Online (Sandbox Code Playgroud)
或者像这样:
<p><span style="font-weight:bold">Security</span> policy</p>
Run Code Online (Sandbox Code Playgroud)
两者都有问题.在第一种情况下,你将需要使用MessageFormat.format()方法和外部化字符串作为(例如)"Security {0}",并"policy"在后者,你会外部化全段(p标签)的内容,包括 span标签.我知道这对翻译来说是痛苦的,但实际上并没有更好的方法.
有时你必须在你的段落中使用动态内容 - JSTL fmt:format标签也会在这里帮助你(它在后端方面使用石灰MessageFormat).
布局
在本地化应用程序中,经常发生翻译的字符串比英语字符串更长.结果可能看起来很丑陋.不知何故,你需要修复样式.还有两种方法:
!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" />
Run Code Online (Sandbox Code Playgroud)
将日期和时间转换为有效(最终用户)的时区非常重要.将它转换为易于理解的格式非常重要 - 这就是我推荐默认格式化风格的原因.
BTW.时区检测并不容易,因为Web浏览器发送任何东西都不是那么好.相反,您可以将首选时区字段添加到用户首选项(如果有的话)或通过客户端脚本从Web浏览器获取当前时区偏移(请参阅Date对象的方法)
数字和货币
数字和货币应转换为本地格式.它以与格式化日期类似的方式完成(解析也类似地完成):
<fmt:formatNumber value="1.21" type="currency"/>
Run Code Online (Sandbox Code Playgroud)
复合消息
您已经被警告不要连接字符串.相反,你可能会使用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?.
Run Code Online (Sandbox Code Playgroud)
字符编码
如果您计划将本地化为不支持ISO 8859-1代码页的语言,则需要支持Unicode - 最好的方法是将页面编码设置为UTF-8.我见过人们这样做:
<%@ page contentType="text/html; charset=UTF-8" %>
Run Code Online (Sandbox Code Playgroud)
我必须警告你:这还不够.你真的需要这个声明:
<%@page pageEncoding="UTF-8" %>
Run Code Online (Sandbox Code Playgroud)
此外,您仍然需要在页眉中声明编码,只是为了安全起见:
<META http-equiv="Content-Type" content="text/html;charset=UTF-8">
Run Code Online (Sandbox Code Playgroud)
我给你的清单并不详尽,但这是一个很好的起点.祝好运 :)
| 归档时间: |
|
| 查看次数: |
7272 次 |
| 最近记录: |