<< 分别使用HttpClient和httpunit处理HTTP Basic Authentication验证登录 | 首页 | 配置acegi与Yale CAS单点登录系统SSO >>

关于JSTL里的资源文件绑定和Locale设置

jstl寻找合适的Locale的过程是:

  1. 看是否通过jsp标签<fmt:setLocale value="zh_CN" />或嵌套的<fmt:bundle设置了Locale,
  2. 找Config是否设置了javax.servlet.jsp.jstl.fmt.locale参数,
  3. 否则就由客户端浏览器的语言设置决定,
  4. 如果没有找到匹配的Locale那么寻找Config里的javax.servlet.jsp.jstl.fmt.fallbackLocale参数

JSTL的message标签,如<fmt:message key="403.title"/>,对Locale=zh能正常显示中文,而对于Locale=zh_CN却不能正常工作。

原因是jstl包里的类org.apache.taglibs.standard.tag.common.fmt.BundleSupport.java居然有BUG:

private static ResourceBundle findMatch(String basename, Locale pref) {
 ResourceBundle match = null;

   try {
       ResourceBundle bundle =
    ResourceBundle.getBundle(basename, pref,
        Thread.currentThread().getContextClassLoader());//执行了这个方法后,下面的bundle.getLocale()方法只要pref参数是zh_CN的将会丢失language和country属性,导致之后的判断失误。
       Locale avail = bundle.getLocale();
       if (pref.equals(avail)) {
       // Exact match
       match = bundle;
       } else {
            if (pref.getLanguage().equals(avail.getLanguage())
        && ("".equals(avail.getCountry()) || pref.getCountry().equals(avail.getCountry()))) {
          match = bundle;
       }
       }
       match = bundle;
   } catch (MissingResourceException mre) {
   }
  
   return match;
}

 

所以使用jstl要使你的Java应用支持包括zh_CN在内的国际化,应该修改jstl源代码BundleSupport.java,重写方法:

private static ResourceBundle findMatch(String basename, Locale pref) {
 ResourceBundle match = null;

   try {
       ResourceBundle bundle =
    ResourceBundle.getBundle(basename, pref,
        Thread.currentThread().getContextClassLoader());
      match=bundle;
   return match;
}

  • 在jsp里绑定特定的资源文件,classpath下有ApplicationResources_zh_CN.properties

             <fmt:setLocale value="zh_CN" />

<fmt:setBundle basename="ApplicationResources" var="applicationBundle"/>

<title><fmt:message key="403.title"/></title>
 <fmt:bundle basename="ApplicationResources">
<content tag="heading"><fmt:message key="403.title" bundle="${applicationBundle}" /></content>

<p>
    <fmt:message key="403.message" bundle="${applicationBundle}">
        <fmt:param><c:url value="/"/></fmt:param>
    </fmt:message>
</p>
</fmt:bundle>

<fmt:bundle basename="labels">
Hello: <fmt:message key="hello" />
Goodbye: <fmt:message key="goodbye" />
</fmt:bundle>

  • 在web.xml里绑定一个资源文件:

 <context-param>
  <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
  <param-value>ApplicationResources</param-value>
 </context-param>

 <context-param>
  <param-name>javax.servlet.jsp.jstl.fmt.fallbackLocale</param-name>
  <param-value>zh_CN</param-value>
 </context-param>
 
 <context-param>
 <param-name>
   javax.servlet.jsp.jstl.fmt.locale
 </param-name>
 <param-value>
   zh_CN
 </param-value>
 </context-param>

 

  • 设置缺省的Locale:

There are two ways to change the default locale. The first is to set it on the command line:

    > java -Duser.language=2-char-language-code -Duser.region=2-char-country-code MyApp
    
    // Set only language code
    > java -Duser.language=fr -Duser.region= MyApp
    // Set language and country code
    > java -Duser.language=fr -Duser.region=CA MyApp

The second way to change the default locale is to call Locale.setDefault():

    // Get default locale
    Locale locale = Locale.getDefault();
    
    // Set the default locale to pre-defined locale
    Locale.setDefault(Locale.FRENCH);
    
    // Set the default locale to custom locale
    locale = new Locale("fr", "CA");
    Locale.setDefault(locale);
  

标签 : ,



发表评论 发送引用通报