第一件事:您可以在您的后端代码中使用ResourceBundle.getBundle(Locale)。但是,您应该永远直接在 JSP 页面中使用它。你应该 use JSTL 代替。现在,让我们进入细节。
没有必要直接使用 ResourceBundle 的好主意有两个原因。一个与此有关:
<%
try {
ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
} catch (MissingResourceException mre) {
// LOG THIS!
}
%>
这看起来很丑,不是吗?那是因为您必须提防MissingResourceException,如果没有您要查找的基本名称的捆绑包,则会抛出该错误。更糟糕的是,如果给定场景中没有密钥,则可能会引发相同的异常:
rb.getString("key");
所以你还需要考虑到这一点:
<%
try {
rb.getString("key");
} catch (MissingResourceException mre) {
// LOG THIS!
}
%>
它看起来怎么样?
当然,您可以从 ResourceBundle 派生并覆盖这些方法,这样它们就不会抛出异常,但这比这要多得多:
<fmt:setLocale value="fr_CA" scope="session"/>
<fmt:bundle basename="com.taglib.weblog.Greeting">
<fmt:message key="com.taglib.weblog.Greeting.greeting">
这就是您应该将 JSTL 与 JSP 一起使用的原因。在this article 中阅读有关如何将 JSTL 用于 i18n 的更多信息。
现在,您最初的问题是关于语言协商(W3C 术语)或区域设置检测(如果您愿意)。如何在 JSP 应用程序中做到这一点?
最简单和最典型的场景是读取 HTTP 的 Accept-Language 标头的内容。在 Java Servlet 世界中,这意味着调用 ServletRequest's getLocale() 或 getLocales() 方法并分配给 HttpSession 对象中的变量,可以从 JSP 页面访问。如果你想知道如何在 servlet 端访问 HttpSession,有一个getSession() 方法。
如果您可以直接访问 Servlet,这将有效。如果您不需要创建(或分配现有的)区域设置过滤器,它将为您完成所有这些工作。正如您可能想象的那样,这是相当常见的情况。这就是人们已经(很久以前)编写必要课程的原因。你可以在几个框架中找到,让我特别提到Spring Framework。
我知道这听起来可能很奇怪,但是如果您正在寻找简单的解决方案,那么学习和使用常见的 Web 框架(即 Spring MVC)比重新发明轮子更好。我知道学习曲线可能有点陡峭,但值得。