java - 如何通过 ResourceBundle 在资源属性中使用 UTF-8

标签 java google-app-engine utf-8 internationalization resourcebundle

我需要使用 Java 的 ResourceBundle 在资源属性中使用 UTF-8。当我将文本直接输入属性文件时,它显示为 mojibake。

我的应用程序在 Google App Engine 上运行。

谁能给我举个例子吗?我无法完成这项工作。

最佳答案

Java 9 及更高版本

From Java 9 onwards属性文件默认编码为 UTF-8,并且使用 ISO-8859-1 之外的字符应该可以开箱即用。

Java 8 及更早版本

ResourceBundle#getBundle()在幕后使用PropertyResourceBundle当指定 .properties 文件时。默认情况下,这又使用 Properties#load(InputStream)加载这些属性文件。根据the javadoc ,它们默认读取为 ISO-8859-1。

public void load(InputStream inStream) throws IOException

Reads a property list (key and element pairs) from the input byte stream. The input stream is in a simple line-oriented format as specified in load(Reader) and is assumed to use the ISO 8859-1 character encoding; that is each byte is one Latin1 character. Characters not in Latin1, and certain special characters, are represented in keys and elements using Unicode escapes as defined in section 3.3 of The Java™ Language Specification.

因此,您需要将它们另存为 ISO-8859-1。如果您有任何超出 ISO-8859-1 范围的字符,并且无法在头顶使用 \uXXXX ,因此被迫将文件保存为 UTF-8,那么您需要使用 native2ascii用于将 UTF-8 保存的属性文件转换为 ISO-8859-1 保存的属性文件的工具,其中所有未覆盖的字符都将转换为 \uXXXX 格式。以下示例将 UTF-8 编码的属性文件 text_utf8.properties 转换为有效的 ISO-8859-1 编码的属性文件 text.properties

native2ascii -encoding UTF-8 text_utf8.properties text.properties

When using a sane IDE such as Eclipse, this is already automatically done when you create a .properties file in a Java based project and use Eclipse's own editor. Eclipse will transparently convert the characters beyond ISO-8859-1 range to \uXXXX format. See also below screenshots (note the "Properties" and "Source" tabs on bottom, click for large):

"Properties" tab "Source" tab

Alternatively, you could also create a custom ResourceBundle.Control implementation wherein you explicitly read the properties files as UTF-8 using InputStreamReader, so that you can just save them as UTF-8 without the need to hassle with native2ascii. Here's a kickoff example:

public class UTF8Control extends Control {
    public ResourceBundle newBundle
        (String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
            throws IllegalAccessException, InstantiationException, IOException
    {
        // The below is a copy of the default implementation.
        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, "properties");
        ResourceBundle bundle = null;
        InputStream stream = null;
        if (reload) {
            URL url = loader.getResource(resourceName);
            if (url != null) {
                URLConnection connection = url.openConnection();
                if (connection != null) {
                    connection.setUseCaches(false);
                    stream = connection.getInputStream();
                }
            }
        } else {
            stream = loader.getResourceAsStream(resourceName);
        }
        if (stream != null) {
            try {
                // Only this line is changed to make it to read properties files as UTF-8.
                bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
            } finally {
                stream.close();
            }
        }
        return bundle;
    }
}

可以按如下方式使用:

ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", new UTF8Control());

另请参阅:

关于java - 如何通过 ResourceBundle 在资源属性中使用 UTF-8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35554453/

相关文章:

java - 是否可以将不可变列表作为 Java 中不可变映射内的值字段?

java - addFilter 和 addListener 的区别

php - Google App Engine 的简单用户管理示例?

mysql - 如何在 MySQL 表中查找搜索字符串的所有变体(重音等)?

java - Hibernate注释一对多

java - 如何将两个 long 转换为字节数组 = 如何将 UUID 转换为字节数组?

python - 谷歌应用程序引擎(gae),python - 将 cron 任务放在哪里?

java - 谷歌应用引擎: CRUDing Instances

utf-8 - utf8_general_ci 或 utf8mb4 或...?

MySQL 将 Unicode 解码为 UTF-8 函数