想要一种更好的方法来使用Java应用程序部署java.util.ResourceBundle属性文件

时间:2014-04-27 04:42:30

标签: java locale resourcebundle

我正在使用java.util.Locale和java.util.ResourceBundle自学Java程序。为此,我编写了一个非常简单的Java应用程序来测试英语,法语和默认语言消息包。该程序工作正常。我在Windows上运行Eclipse Kepler SR2。

我的问题与ResourceBundle.getBundle使用的属性文件的部署有关(我将在下面讨论我的问题),但首先介绍一下我在设置演示应用程序并部署它时所尝试的内容。 / p>

当我第一次调用ResourceBundle.getBundle时(请参阅下面的LocaleWrapper.java),我发现它搜索的路径默认为部署bin文件夹。

ResourceBundle Javadoc没有谈论部署文件夹,我所关注的Oracle tutorial on Java internationalization也没有。

因此,为了避免将我的属性文件全部转储到bin中,我决定为我的语言环境包装类创建一个单独的包(demo.locale),并将所有属性文件添加到该包中,如下所示:

我的名为LocaleDemo的Eclipse项目包含2个包中的5个源文件,如下所示:

src/demo/DemoApp.java
src/demo.locale/LocaleWrapper.java (wraps java.util.Locale, java.util.ResourceBundle)
src/demo.locale/MessageBundle.properties (default messages, same as English/US)
src/demo.locale/MessageBundle_en_US.properties (English/US messages)
src/demo.locale/MessageBundle_fr_FR.properties (French/France messages)

部署应用程序时,它最终会在bin文件夹下,如下所示:

bin/demo/DemoApp.class
bin/demo/locale/LocaleWrapper.class
bin/demo/locale/MessageBundle.properties
bin/demo/locale/MessageBundle_en_US.properties
bin/demo/locale/MessageBundle_fr_FR.properties

(为清楚起见,我从这些列表中排除了包信息文件。)

所以要了解我的实际问题:

我对这种类型的部署的关注是它将属性文件与类文件混合在一起。

我尝试通过在Ecipse中创建与我的src文件夹相同级别的数据文件夹来分隔它们,然后将所有属性文件放在那里,并将数据文件夹添加到我的构建路径中;但是,当我部署应用程序时,所有属性文件只会最终位于包文件夹上方顶层的bin文件夹中(例如bin / MessageBundle.properties)。

这不太令人满意,所以我还是将它们与demo.locale包一起使用。我确定的布局在this stackoverflow question中被接受为答案:

但是,我同意该线程中的另一张海报,他说要分离类和数据,这是我更喜欢的,但没有给出如何做到这一点的例子。

这就是我的问题:Eclipse中是否有一种干净的方法为应用程序创建一个独特的数据文件夹,并将属性文件部署在该文件夹中,而不仅仅是转储到项目的根文件夹中,这就是发生的事情我试过的时候。

我正在寻找一些程序员所做过的具体例子,甚至更好地参考一些关于这个主题的官方文档 - 我找不到任何具体的提及如何在实践中做到这一点,只有一般性。

作为附录,我在下面列出了我的两个Java类的源代码。我使用的资源文件直接来自我上面链接的Oracle教程。

DemoApp.java

package demo;

import demo.locale.LocaleWrapper;

public class DemoApp {

    public static void main(String[] args) {

        LocaleWrapper intl = null;

        // English/USA
        intl = new LocaleWrapper("en", "US");
        doTest(intl);

        // French/France
        intl.changeLocale("fr",  "FR");
        doTest(intl);

        // non-existent language/country will use default
        intl.changeLocale("sp", "MX");
        doTest(intl);

    }

    private static void doTest(LocaleWrapper intl) {
        System.out.println("Testing: " + intl.getLanguage() + "_" + intl.getCountry());
        System.out.println("  " + intl.getString("greetings"));
        System.out.println("  " + intl.getString("farewell"));
        System.out.println("  " + intl.getString("inquiry"));
        System.out.println();
    }
}

LocaleWrapper.java

package demo.locale;

import java.util.Locale;
import java.util.ResourceBundle;

/**
 * Internationalization using java.util.Locale and java.util.ResourceBundle.
 */
public class LocaleWrapper {

    private static final String PATH = "demo/locale/MessageBundle";

    private String language = null;
    private String country = null;
    private Locale locale = null;
    private ResourceBundle messages = null;

    public LocaleWrapper(String language, String country) {
        super();
        this.language = language;
        this.country = country;
        this.locale = new Locale(language, country);
        messages = ResourceBundle.getBundle(PATH, this.locale);
    }

    public void changeLocale(String language, String country) {
        this.language = language;
        this.country = country;
        this.locale = new Locale(language, country);
        messages = ResourceBundle.getBundle(PATH, this.locale);
    }

    /**
     * Get an internationalized string based on it's key.
     * 
     * @param key
     *            Message key.
     * @return Internationalized message string.
     */
    public String getString(String key) {
        return messages.getString(key);
    }

    // getters

    public String getLanguage() {
        return language;
    }

    public String getCountry() {
        return country;
    }

}

1 个答案:

答案 0 :(得分:2)

唐。你只是提出一个很长的问题。

您可以指定资源包来存放资源包。

我研究问题10911708并做一个示例程序,它可以工作。

这是我做的:

Step1:在与src(我使用eclipse)文件夹相同的级别创建一个资源文件夹(在这里,我将其命名为resource),并将属性文件放在此文件夹中。

请记住使用native2ascii将文本编码为不同的languange utf8,如:

native2ascii -encoding utf8 MessagesBundle_zh_CN.properties

然后你得到:

greetings = \u4f60\u597d.(你好)
farewell = \u518d\u89c1.(再见)
inquiry = \u4f60\u597d\u5417?(你好吗?)

将这些utf8文本保存到属性文件中,否则会出现乱码。

step2:两种情况:

A。访问jar文件中的资源包(将项目打包到可运行的jar) 在您的代码中,访问源包,如:

 Locale currentLocale = new Locale(language, country);

  ResourceBundle messages =
    ResourceBundle.getBundle("resource.MessagesBundle",currentLocale);

  System.out.println(messages.getString("greetings"));
  System.out.println(messages.getString("inquiry"));
  System.out.println(messages.getString("farewell"));

B。在eclipse项目中访问您的资源包。

您应该单击项目属性,并在java构建路径中添加资源文件夹

然后eclipse会自动将这些文件复制到bin derectory中, 你应该写道:

ResourceBundle messages =
        ResourceBundle.getBundle("MessagesBundle",currentLocale);

没有前缀"资源"。

我在jar文件中的测试结果是:

D:\>java -jar Sample.jar zh CN
你好.
你好吗?
再见.

你可以从oracle website获得这个演示,希望它有所帮助!