整个文件的"ResourceBundle"?

sjn*_*ngm 5 java resourcebundle

显然ResourceBundle需要在找到的文件中使用类似语法的属性文件.

我们有一种情况,我们想要将整个文件(在我们的例子中是HTML文件)用作"值".这意味着我们没有这样的密钥.好吧,也许文件名可以作为密钥.

这是一个目录树:

src/
    main/
        resources/
            html/
                content.html
                content_de.html
                content_fr.html
                content_es.html
                order.html
                order_de.html
                order_fr.html
                order_es.html
Run Code Online (Sandbox Code Playgroud)

现在我们需要逻辑来根据当前的语言环境找到正确的文件.如果当前的语言环境是德语,我正在查找html/content.html文件,它应该找到html/content_de.html.它不一定需要立即加载它.Java中是否存在一些现有机制?我们需要手动完成吗?

由于某些限制,我们目前正计划不使用任何第三方库.因此,如果Java 6 SE中有可用的东西,它将是我们的最佳选择; 但是,如果您知道第三方库,请随意命名.

编辑#1:一个明显的解决方案是使用密钥messages.properties来命名该HTML文件.虽然这会起作用,但从长远来看它可能会成为一个痛苦(除此之外,我不认为这会解决我们所有的问题).

编辑#2:我忘了说这是一个桌面应用程序.

sjn*_*ngm 1

为了表明我没有做什么,这里有两次使用“我们自己”方法的尝试:

第一次尝试构建 locale-postfix 并直接加载资源:

  public void attempt1(String baseName, String extension) {
    List<String> locales = buildLocaleStrings(Locale.getDefault());
    String resourceFound = null;

    for (String locale : locales) {
      String resourceName = baseName + locale + "." + extension;
      URL resource = getClass().getClassLoader().getResource(resourceName);
      if (resource != null) {
        resourceFound = resourceName;
        break;
      }
    }
    System.out.println("found #1: " + resourceFound);
  }

  private List<String> buildLocaleStrings(Locale localeBase) {
    String locale = "_" + localeBase;
    List<String> locales = new ArrayList<String>();

    while (locale.length() > 0) {
      locales.add(locale);
      locale = locale.replaceFirst("_[^_]*?$", "");
    }
    locales.add("");

    return locales;
  }
Run Code Online (Sandbox Code Playgroud)

第二次尝试“滥用”ResourceBundle及其toString()

  public void attempt2(String baseName, final String extension) {
    ResourceBundle.Control control = new ResourceBundle.Control() {

      private String resourceFound = null;

      @Override
      public List<String> getFormats(String baseName) {
        return Arrays.asList(extension);
      }

      @Override
      public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, format);

        if (loader.getResource(resourceName) != null) {
          resourceFound = resourceName;
          return new ResourceBundle() {

            @Override
            public Enumeration<String> getKeys() {
              return null;
            }

            @Override
            protected Object handleGetObject(String key) {
              return null;
            }

          };
        }
        return null;
      }

      @Override
      public String toString() {
        return resourceFound;
      }
    };

    ResourceBundle.getBundle(baseName, control);

    System.out.println("found #2: " + control.toString());
  }
Run Code Online (Sandbox Code Playgroud)

调用示例:

  public void proof() {
    attempt1("html/content", "html");
    attempt2("html/content", "html");
  }
Run Code Online (Sandbox Code Playgroud)

两者都找到相同的文件。

说实话,我都不喜欢。