Java JSP/Servlet中的多语言支持

Java JSP/Servlet中的多语言支持,java,jsp,servlets,jakarta-ee,Java,Jsp,Servlets,Jakarta Ee,如何通过JSP/Servlet提供多语言支持?如何根据所选语言在运行时包含不同语言的静态数据?此问题有几个重要方面。第一部分是确定每个请求的区域设置。您可以使用以下内容: HttpServletRequest req ...; String browserLocale = req.getHeader("Accept-Language"); // typically something like 'en' 接下来,您需要决定如何管理站点的本地化内容。最类似Java的(不一定是最好的)方法是使用R

如何通过JSP/Servlet提供多语言支持?如何根据所选语言在运行时包含不同语言的静态数据?

此问题有几个重要方面。第一部分是确定每个请求的区域设置。您可以使用以下内容:

HttpServletRequest req ...;
String browserLocale = req.getHeader("Accept-Language"); // typically something like 'en'
接下来,您需要决定如何管理站点的本地化内容。最类似Java的(不一定是最好的)方法是使用ResourceBundle将所有消息外部化。您可以在其手册中了解I18N、G13N的核心Java功能

在我看来,仅仅使用这种方法是相当糟糕的。不同语言的内容大小不同,与不同的布局匹配更好,等等。因此,您可以完全消除资源包(如果您没有大量的多语言环境数据),或者通过使用XSLT或其他特定于语言环境的模板来扩充该方法

一种性能非常好但开发开销很大的方法是使用servlet过滤器将流量重定向到特定于语言(或区域设置)的子网站。在这种情况下,任何点击
的人都会被重定向到
en/xyz

最后,值得注意的是,大多数严肃的web框架都有自己的I18N支持。它们的方法基于框架原理而有所不同。

在“普通”JSP/Servlet应用程序中,最好的解决方案是。(只需输入
/WEB-INF/lib
)如何使用它在本答案中有介绍:

如果您使用的是MVC框架,如Oracle JSF或Apache Struts,那么您需要使用关键字“国际化”(i18n)或“本地化”(l10n)查阅其特定文档。在大多数情况下,它们还为此提供了特定的标记,例如JSF中的
,本章将介绍这一点

这些i18n标记已经通过检查默认语言/区域设置(您不需要像之前建议的那样通过检查头来“低级别”地执行此操作——这将涉及更多的工作,按照建议解析头)。您可以让用户选择语言本身(下拉?),并将其存储在会话作用域中,并指示这些标记库使用它。以下是JSTL fmt taglib的一个示例:


…其中,
${someSessionBean.locale}
可以返回
en
en_-US
en_-UK
等。这些反过来被API用来加载本地化文本(您不需要创建/加载
ResourceBundle
本身,taglib已经做到了这一点,只需阅读链接的javadoc就可以了解它的工作原理)


如果希望该语言作为URL的第一个pathinfo部分可用(例如
http://example.com/en/
,这对搜索引擎优化最有利),然后您可以最好使用一个
过滤器
,该过滤器监听
/*
,检查路径信息,从中分割语言部分,将其存储/比较为/与会话值,并将路径信息中没有语言部分的请求进一步转发到所需的前端控制器。

我们可以创建messages.properties,messages\u绑定并将此文件放入/scr/java目录中。(其中??-en_US、ru_ru和其他)

messages.properties中的示例行:

About = About
Buy = Buy
Company = Company
ContactUs = Contact Us 
然后粘贴到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);
   }

现在,您可以将${name}粘贴到下一个jsp代码(${About},${Buy},…)

这不是您使用
ResourceBundle
Locale
类的方式!它显示了对主题的基本理解不足。
ServletRequest.getLocale()
的存在是有原因的!