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/59070570/

相关文章:

java - 如何在将 blob 上传到 Blobstore 的 POST 请求中提交文本字段,并在 blob 的上传处理程序中检索它?

c++ - 使用 Qt 检测和打印 Unicode 字符

java - 使用 Java 将 ASCII 转换为 UTF-16

java - 没有重定向的 Shiro 过滤器

java - 如果包含在 log.isDebugEnabled() 下,slf4j 记录器不会在 springboot 的控制台中打印日志

java - org.springframework.orm.hibernate4.annotation.AnnotationSessionFactoryBean

google-app-engine - 我怎样才能在谷歌应用引擎上获得 https 响应?

java - ":P"在 JDO 查询中意味着什么

java - JAX-RS json (java.util.Date) 序列化的不同行为

rest - Delphi XE3 - datasnap REST 服务器 UTF8 输出