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

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

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

Ä, Ö, Ü, ß. ä, ö, ü 以及特殊字符,如 “ 或 ”

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

资源捆绑:

executeShellCommand.label = Shellkommando ausführen

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

资源捆绑使用 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;
    }
}

如果我检查上述系统输出,我会得到以下结果:getLocalizedString, key: executeShellCommand.label, resourcebundle: Shellkommando ausführen

似乎getString(key)方法在从捆绑包读取字符时更改了字符的编码,并将其读取到标准资源编码(ISO-8859)。

我试图解决这个问题:

    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;
    }
}

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

enter image description here

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

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


答案 1

Java ResourceBundles假定ISO-8859。我认为你需要使用属性而不是资源捆绑。

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

答案 2

这是怎么回事!!!

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);