ResourceBundle 中文乱码问题解决
ResourceBundle 中文乱码问题解决
问题
国际化 i18n 中文的配置文件 i18n_zh_CN.properties 内容如下:
1 | username=用户名 |
下面 bundle.getString 会输出乱码:
1 |
|
原因
Java 读取 .properties 文件时默认使用的编码是 ISO-8859-1,ISO-8859-1 是单字节编码,自身不能显示中文,因此导致了乱码现象。
解决方案
方案一
将 bundle.getString 获取到的内容按 ISO-8859-1 单字节编码形式进行转换,得到对应的 byte[] 字节数组,然后使用 new String(byte[] bytes, String charsetName) 构造器再将 byte[] 字节数组转换为 utf-8 格式的字符串。
1 | new String(bundle.getString("username").getBytes("ISO-8859-1"), "utf-8"); |
这种方法的缺点在于,每次 bundle.getString 都需要手工进行转换,如果需要进行国际化的文本信息很多,这种方法需要大量的手工转换,同时也造成代码冗余且可读性很差。
另外,在 jsp 页面中使用表达式脚本,尚能使用该方案:
1 | <%=new String(bundle.getString("username").getBytes("ISO-8859-1"), "utf-8")%> |
但如果希望使用 jstl 标签库中的 <fmt:message> 标签来进行国际化信息输出,显然该方案就无法使用了。
方案二
使用 Java SDK 提供的转码 native2ascii.exe 工具(在 bin 目录下可以找到)
首先将原文件 i18n_zh_CN.properties 重命名为 i18n_zh.properties
然后进入 i18n_zh.properties 所在的文件目录,使用如下命令进行转码(指定转换为 UTF-8 编码)
1 | native2ascii -encoding utf-8 i18n_zh.properties i18n_zh_CN.properties |
命令执行完后,会生成 i18n_zh_CN.properties 文件,该文件已经经过转码处理,原文件的中文在该文件中已经转码为 Unicode,如下:
1 | username=\u7528\u6237\u540d |
补充说明:native2ascii 命令的 -encoding 参数表示转换为指定编码。Web 项目中一般统一使用 UTF-8 编码,因此我们这里指定转换为 UTF-8 编码。