ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Tomcat的国际化实现

2021-05-14 22:56:03  阅读:241  来源: 互联网

标签:国际化 String Tomcat 实现 packageName bundle locale null StringManager


对于涉及到多语言用户使用的应用,国际化是一条必经之路。Tomcat也不例外,做为一款成熟且成功的开源软件,其用户量巨大,受到全球各国的工程师喜爱。

我们在阅读其源码时,一定见到过类似下面这样的内容:

throw new IllegalArgumentException(sm.getString("coyoteConnector.parseBodyMethodNoTrace"));

其中这句sm.getString("coyoteConnector.parseBodyMethodNoTrace")里的sm,就是实现国际化的核心StringManager。 在许多类中,我们都会发现这样的字段声明:

/**     * The string manager for this package.     */    protected static final StringManager sm = StringManager.getManager(Connector.class);


此时,会得到一个当前Locale对应的StringManager。注意这里保证每个包只对应一个manager。单例的实现可以参考前面的文章:

来看看你貌似熟悉的单例模式


public static final synchronized StringManager getManager(            String packageName, Locale locale){         Map<Locale,StringManager> map = managers.get(packageName);        if (map == null) {            map = new LinkedHashMap<Locale,StringManager>(LOCALE_CACHE_SIZE, 1, true);            managers.put(packageName, map);        }         StringManager mgr = map.get(locale);        if (mgr == null) {            mgr = new StringManager(packageName, locale);            map.put(locale, mgr);        }        return mgr;    }


资源文件的载入是使用ResourceBundle实现的,文件是对应的packageName+LocalStrings

private StringManager(String packageName, Locale locale) {        String bundleName = packageName + ".LocalStrings";        ResourceBundle bnd = null;        try {            bnd = ResourceBundle.getBundle(bundleName, locale);        } catch (MissingResourceException ex) {        }        bundle = bnd;        if (bundle != null) {            Locale bundleLocale = bundle.getLocale();            if (bundleLocale.equals(Locale.ROOT)) {                this.locale = Locale.ENGLISH;            } else {                this.locale = bundleLocale;            }        } else {            this.locale = null;        }    }

这块有两个可以关注的点:

  • ResourceBundle

  • MessageFormat

其中ResourceBundle会根据指定的Locale加载对应的资源文件信息,我们一般资源文件都是xxx_fr.properties/xxx_es.properties这种形式,bundle的locale会自动匹配。

图片

MessageFormat则会自动替换信息中的占位符,例如资源文件中有类似这样的内容:

Could not contact {0}:{1}. Tomcat may not be running.

其中{0}:{1}就是占位符,在实际使用时,会被真实的值替换。而背后的实现,正是MessageFormat.使用时,就直接传入实际值即可,如下:

 log.error(sm.getString("catalina.stopServer.connectException",                                       s.getAddress(),                                       String.valueOf(s.getPort())));`

在需要信息提示时,调用方法getString来获取,注意catch块中的注释,比较有意思。

public String getString(String key) {        if (key == null){            String msg = "key may not have a null value";            throw new IllegalArgumentException(msg);        }         String str = null;         try {            // Avoid NPE if bundle is null and treat it like an MRE            if (bundle != null) {                str = bundle.getString(key);            }        } catch (MissingResourceException mre) {            //bad: shouldn't mask an exception the following way:            //   str = "[cannot find message associated with key '" + key +            //         "' due to " + mre + "]";            //     because it hides the fact that the String was missing            //     from the calling code.            //good: could just throw the exception (or wrap it in another)            //      but that would probably cause much havoc on existing            //      code.            //better: consistent with container pattern to            //      simply return null.  Calling code can then do            //      a null check.            str = null;        }         return str;    }

以上,即为Tomcat国际化的实现方式,对于我们的应用开发,可以用来参考。


标签:国际化,String,Tomcat,实现,packageName,bundle,locale,null,StringManager
来源: https://blog.51cto.com/u_15127648/2776666

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有