部署后加载了错误的资源包

时间:2015-04-03 07:51:08

标签: java java-ee internationalization resourcebundle

我遇到一个奇怪的问题:我的应用程序在本地IDE运行时(IDEA,Windows 7,lang =中文)可以很好地加载资源。但是在我将战争部署到Linux之后,出现了一些非常奇怪的问题。

问题包含在此日志中:

[LangService#getInstance]: lang = zh_CN, resourceBundle: en's instance is returned

这意味着客户需要中文服务,但它会给我英文服务。

但是,当我在IDEA运行时,应用程序运行良好,无论是我的还是我的同事(eclipse)。

三个属性文件是:

strings.properties //Chinese text 
strings_en.properties//English text
strings_zh_CN.properties//Chinese text

一些相关代码(我使用Singleton模式返回LangService的两个单例):

public class LangService {

/*******************static variable*****************/

/***constants*****/
public static final String LANG_ENGLISH = "en";
public static final String LANG_CHINESE = "zh_CN";//Chinese
private static final String RESOURCE_PATH = "bundle.strings";

private static Log log = LogFactory.getLog(LangService.class);


/**
 * Chinse service and RB*
 */
private static  ResourceBundle zhRB;
private static  LangService zhService;
static {
    try{
        zhRB = ResourceBundle.getBundle(RESOURCE_PATH, new Locale(LANG_CHINESE));
        zhService =  new LangService(LANG_CHINESE);
    }
}


/**English Service , lazy instantiation**/
private static  ResourceBundle enRB = null ;
private static  LangService enService =  null;

/******************instance variale*********************/
private ResourceBundle resourceBundle = zhRB;//Chinese RB by default

//private constructor
private LangService(String lang){
    ResourceBundle rb = zhRB;//by default, this will be Chinese RB

    if(checkEnglish(lang)){
        if (null ==enRB ){//English RB is not loaded yet
            enRB = ResourceBundle.getBundle(RESOURCE_PATH, new Locale(LANG_ENGLISH));
        }
        rb = enRB;
    }

    this.resourceBundle= rb;// set rb accordingly
}


public static synchronized LangService getInstance(String lang){
    LangService instance = zhService;//Chinese service by default

    if(checkEnglish(lang)){//want English service 
        if (enService ==null){//not init yet
            enService =  new LangService(LANG_ENGLISH);
        }
        instance = enService;
    }
    log.info("[LangService#getInstance]: lang = " +lang + ", resourceBundle: "+instance.resourceBundle.getLocale() +"'s instance is returned");//here , we can see the problem
    return instance;
}


private static boolean checkEnglish(String lang){
    if(lang == null|| "".equals(lang)) return false;
    return LANG_ENGLISH.equals(lang) || lang.startsWith("en");
}

}

1 个答案:

答案 0 :(得分:0)

你遇到的错误是微不足道的:

new Locale(LANG_CHINESE)

鉴于你已经定义了这样的常量:

public static final String LANG_CHINESE = "zh_CN";

它真的变成了:

zhRB = ResourceBundle.getBundle(RESOURCE_PATH, new Locale("zh_CN"));

问题是,Locale类中没有这样的构造函数会使用Java语言环境标识符,而是有其他选择:

A)使用两个参数构造函数:

Locale chineseLocale = new Locale("zh", "CN");

B)使用预定义的Locale常量:

Locale chineseLocale = Locale.CHINA;

C)从Java 7开始,使用语言标记:

public static final String SIMPLIFIED_CHINESE = "zh-CN";
Locale chineseLocale = Locale.forLanguageTag(SIMPLIFIED_CHINESE);

就个人而言,我更喜欢最后一个,但这实际上取决于你的环境。