java JSP/Servlet 中的多语言支持
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2182370/
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
MUlti Language support in JSP/Servlet
提问by bhardwaj
How to provide multi language support through JSP/Servlet? How to include static data of different languages at run time on basis of language selected?
如何通过 JSP/Servlet 提供多语言支持?如何根据所选语言在运行时包含不同语言的静态数据?
回答by BalusC
In a "plain vanilla" JSP/Servlet application, the best solution is the JSTLfmt taglib. (just drop jstl-1.2.jarin /WEB-INF/lib) How to use it is covered in Oracle Java EE 5 tutorial part II chapter 7and in this answer: How to internationalize a Java web application?.
在“普通”JSP/Servlet 应用程序中,最好的解决方案是JSTL fmt taglib。(只需jstl-1.2.jar加入/WEB-INF/lib)Oracle Java EE 5 教程第二部分第 7 章和这个答案中介绍了如何使用它:如何国际化 Java Web 应用程序?.
If you're using a MVC framework such as Oracle JSF or Apache Struts, then you need to consult its specific documentation using keywords "internationalization" (i18n) or "localization" (l10n). In most cases they also provides specific tags for that, such as <f:loadBundle>in case of JSF, which in turn is covered in Oracle Java EE 5 tutorial part II chapter 15.
如果您使用的是 MVC 框架,例如 Oracle JSF 或 Apache Struts,那么您需要使用关键字“国际化”(i18n) 或“本地化”(l10n) 查阅其特定文档。在大多数情况下,它们还为此提供了特定的标记,例如<f:loadBundle>JSF,这在Oracle Java EE 5 教程第二部分第 15 章中进行了介绍。
Those i18n tags already checks the default language/locale by ServletRequest#getLocale()(you don't need to do it "low-level" by checking the header as one suggested before --which would involve more work parsing the header as per the HTTP spec). You can let the user choose the language itself (dropdown?) and store it in the session scope and instruct those taglibs to use it. Here's an example with JSTL fmt taglib:
那些 i18n 标签已经通过以下方式检查默认语言/区域设置ServletRequest#getLocale()(您不需要按照之前的建议通过检查标头来“低级”执行此操作——这将涉及根据HTTP 规范解析标头的更多工作)。您可以让用户选择语言本身(下拉菜单?)并将其存储在会话范围内,并指示这些标签库使用它。这是一个带有 JSTL fmt taglib 的示例:
<fmt:setLocale value="${someSessionBean.locale}" />
..where ${someSessionBean.locale}can return en, en_US, en_UK, etc. Those are in turn used by the java.util.ResourceBundleAPI to load the localized text (you don't need to create/load the ResourceBundleitself, the taglibs already do that, just read the linked javadoc to learn a bit more about how it works).
..where${someSessionBean.locale}可以返回en, en_US,en_UK等。java.util.ResourceBundleAPI依次使用它们来加载本地化文本(您不需要创建/加载ResourceBundle本身,标签库已经这样做了,只需阅读链接的 javadoc 以了解更多关于它是如何工作的)。
If you want the language available as first pathinfo part of URL (such as http://example.com/en/, which is best for SEO), then you can best use a Filterfor this which listens on /*, checks the pathinfo, splits the language part from it, stores/compares it as/with session value and forwards the request without language part in pathinfo further to the desired front controller.
如果您希望该语言可用作 URL 的第一个路径信息部分(例如http://example.com/en/,这最适合 SEO),那么您最好使用Filter它来监听/*、检查路径信息、从中分离语言部分、存储/比较它as/with session value 并将 pathinfo 中没有语言部分的请求进一步转发到所需的前端控制器。
回答by Dilum Ranatunga
There are several important aspects to this issue. The first part is determining each request's locale. You can use something like this:
这个问题有几个重要方面。第一部分是确定每个请求的区域设置。你可以使用这样的东西:
HttpServletRequest req ...;
String browserLocale = req.getHeader("Accept-Language"); // typically something like 'en'
Next, you need to decide how to manage the site's localized content. The most Java-like (not necessarily the best) approach is to externalize all messages using a ResourceBundle. You can learn about the core Java facilities for I18N, G13N in their Isolating Locale Specific Data tutorial.
接下来,您需要决定如何管理站点的本地化内容。最类似于 Java(不一定是最好的)的方法是使用 ResourceBundle 将所有消息外部化。您可以在Isolating Locale Specific Data 教程 中了解 I18N、G13N 的核心 Java 工具。
Using only this approach is quite poor in my opinion. Different languages' content size differently, match better with different layouts, etc. So you can completely eliminate resource bundles (if you don't have a lot of multi-locale data) or augment the approach by using XSLT or other templating that is locale specific.
在我看来,只使用这种方法是很糟糕的。不同语言的内容大小不同,与不同的布局更好地匹配等。因此您可以完全消除资源包(如果您没有大量多语言环境数据)或通过使用 XSLT 或其他语言环境模板来增强该方法具体的。
One very performant but high-development overhead approach is to use a servlet filter to redirect traffic to language- (or locale-) specific subsites. In this case, anyone hitting http://my.domain.fake/xyzwould get redirected to http://my.domain.fake/en/xyz
一种非常高效但开发开销很大的方法是使用 servlet 过滤器将流量重定向到特定于语言(或区域设置)的子站点。在这种情况下,任何击中的人http://my.domain.fake/xyz都会被重定向到http://my.domain.fake/en/xyz
Finally, it is worth noting that most of the serious web frameworks have their own I18N support. Their approaches differ based on the framework philosophy.
最后,值得注意的是,大多数严肃的 web 框架都有自己的 I18N 支持。他们的方法因框架哲学而异。
回答by ShelS
We can to create messages.properties, messages_????.properties and to place this files into /scr/java directory. (where ???? - en_US, ru_RU and other)
我们可以创建messages.properties、messages_?? ??.properties 并将此文件放入 /scr/java 目录。(哪里 ???? - en_US、ru_RU 和其他)
Example lines into messages.properties:
message.properties 中的示例行:
About = About
Buy = Buy
Company = Company
ContactUs = Contact Us
Then to paste into jsp file for example lines:
然后粘贴到jsp文件中,例如:
Locale locale = Locale.getDefault();
String lng = locale.getCountry();
session.setAttribute( "language", lng);
if (lng.equals( "UA"))
locale = new Locale( "uk", "UA");
else if (lng.equals( "RU"))
locale = new Locale( "ru", "RU");
else
locale = Locale.US;
ResourceBundle boundle = ResourceBundle.getBundle( "messages", locale);
for (Enumeration e = boundle.getKeys(); e.hasMoreElements(); ) {
String key = (String) e.nextElement();
String s = boundle.getString(key);
session.setAttribute( key, s);
}
Now you can paste ${name} into next jsp code (${About}, ${Buy}, ...).
现在您可以将 ${name} 粘贴到下一个 jsp 代码中(${About}, ${Buy}, ...)。

