java 将资源包读取为 UTF-8。getString() 方法似乎将编码更改为 ISO-8859

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25053710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 07:14:09  来源:igfitidea点击:

read resourcebundle as UTF-8. getString() Method seems to change encoding to ISO-8859

javaencodingutf-8propertiesresourcebundle

提问by izocan

I have the honorable assignment to change the encoding of our complete workspace, projects and files to the UTF-8 encoding. We have several Resourcebundles which used to code special chars with unicode. We also wanted to get rid of that unicode stuff by switching to UTF-8 so I changed the encoding of the Resourcebundles (.properties) files too and replaced the Unicode characters.

我有一项光荣的任务,将我们整个工作区、项目和文件的编码更改为 UTF-8 编码。我们有几个 Resourcebundle,用于使用 unicode 编码特殊字符。我们还想通过切换到 UTF-8 来摆脱那些 unicode 的东西,所以我也更改了 Resourcebundles (.properties) 文件的编码并替换了 Unicode 字符。

We also have german resourcebundles and some chars like

我们还有德国资源包和一些字符,比如

?, ?, ü, ?. ?, ?, ü and also special characters like ? or “

?, ?, ü, ?. ?, ?, ü 以及特殊字符,如 ? 或者 ”

are not shown properly in the browser. Example:

未在浏览器中正确显示。例子:

Resourcebundleentry:

资源包入口:

executeShellCommand.label = Shellkommando ausführen

executeShellCommand.label = Shellkommando ausführen

Result in browser: enter image description here

结果在浏览器中: enter image description here

The resourcebundles are read with the Java.util.ResourceBundle.getString(String key) Method:

使用 Java.util.ResourceBundle.getString(String key) 方法读取资源包:

    public String getLocalizedString(ResourceBundle bundle, String key) {
    try {
        System.out.println("getLocalizedString, key: " + key + ", resourcebundle: " + bundle.getString(key));
        return bundle.getString(key);
    } catch (MissingResourceException e) {
        return key;
    }
}

If i check the output of the above Sysout i get following: getLocalizedString, key: executeShellCommand.label, resourcebundle: Shellkommando ausf??hren

如果我检查上述 Sysout 的输出,我会得到以下信息: getLocalizedString, key: executeShellCommand.label, resourcebundle: Shellkommando ausf??hren

It seems that the getString(key) method changes the encoding of the chars while readingthem from the bundles to the standard resourcbundleencoding(ISO-8859).

似乎getString(key) 方法在从包中读取字符时将字符的编码更改为标准 resourcbundleencoding(ISO-8859)。

I tried to counter this issue:

我试图反驳这个问题:

    public String getLocalizedString(ResourceBundle bundle, String key) {
    try {
        System.out.println("getLocalizedString, key: " + key + ", resourcebundle: " + new String (bundle.getString(key).getBytes(), "UTF-8"));
        return new String (bundle.getString(key).getBytes(), "UTF-8");
    } catch (MissingResourceException e) {
        return key;
    } catch (UnsupportedEncodingException e) {
        return key;
    }
}

This helped to recover the most special characters but there are still a plenty of them which are not shown properly:

这有助于恢复最特殊的字符,但仍有很多未正确显示:

enter image description here

enter image description here

I also checked the content-type configuration of the WebApp and of every single request which gets the resource bundles everything is utf-8.

我还检查了 WebApp 和每个获取资源包的请求的内容类型配置,一切都是 utf-8。

Does anyone have an idea how to prevent the getString()-Method from changing the encodingor is there a better way to solve this issue?

有没有人知道如何防止 getString()-Method 更改编码,或者有没有更好的方法来解决这个问题?

采纳答案by lance-java

Java ResourceBundles assume ISO-8859. I think you'll need to use Properties instead of ResourceBundle.

Java ResourceBundles 采用 ISO-8859。我认为您需要使用 Properties 而不是 ResourceBundle。

InputStream utf8in = getClass().getClassLoader().getResourceAsStream("/path/to/utf8.properties");
Reader reader = new InputStreamReader(utf8in, "UTF-8");
Properties props = new Properties();
props.load(reader);

回答by lance-java

How's this for a hack!!!

这对黑客来说如何!!!

public class HackClassLoader extends ClassLoader {

    public HackClassLoader(ClassLoader parent) {
        super(parent);
    }

    @Override
    public InputStream getResourceAsStream(String name) {
        InputStream utf8in = getParent().getResourceAsStream(name);
        if (utf8in != null) {
            try {
                byte[] utf8Bytes = new byte[utf8in.available()];
                utf8in.read(utf8Bytes, 0, utf8Bytes.length);
                byte[] iso8859Bytes = new String(utf8Bytes, "UTF-8").getBytes("ISO-8859-1");
                return new ByteArrayInputStream(iso8859Bytes);
            } catch (IOException ex) {
                throw new RuntimeException("Could not load " + name, e);
            } finally {
                utf8in.close();
            }
        }
        return null;
    }
}

ClassLoader hackLoader = new HackClassLoader(getClass().getClassLoader());
ResourceBundle bundle = ResourceBundle.getBundle("foo", Locale.UK, hackLoader);