为何ResourceBundle输出乱码?Web应用国际化编码问题求助
解决ResourceBundle读取国际化资源乱码问题
看起来你遇到的是ResourceBundle默认编码不兼容导致的乱码问题,输出的那段乱码其实是UTF-8编码的俄文被当成ISO-8859-1解析后的结果。我来给你几个可行的解决方案:
方案一:转换属性文件的编码格式
ResourceBundle默认会用ISO-8859-1编码读取.properties文件,如果你的资源文件是UTF-8保存的,就会出现乱码。你可以把文件里的非ASCII字符转换成Unicode转义序列,用JDK自带的native2ascii工具就能处理:
- 命令行执行:
native2ascii -encoding UTF-8 messages_ru.properties messages_ru_iso.properties - 之后用转换后的
messages_ru_iso.properties作为国际化资源文件,ResourceBundle读取时就能正确解析内容。
方案二:自定义ResourceBundle.Control强制UTF-8读取
从Java 1.6开始,我们可以通过自定义ResourceBundle.Control来指定用UTF-8读取属性文件,不用转义字符也能直接使用,修改后的代码如下:
Locale locale = new Locale(language); ResourceBundle.Control control = new ResourceBundle.Control() { @Override public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException { // 仅处理properties格式的资源文件 if (!"java.properties".equals(format)) { return super.newBundle(baseName, locale, format, loader, reload); } String bundleName = toBundleName(baseName, locale); String resourceName = toResourceName(bundleName, "properties"); try (InputStream stream = loader.getResourceAsStream(resourceName)) { if (stream == null) { return null; } // 指定UTF-8编码读取资源文件 return new PropertyResourceBundle(new InputStreamReader(stream, StandardCharsets.UTF_8)); } } }; ResourceBundle messages = ResourceBundle.getBundle("i18n.messages", locale, control); try { String message = messages.getString(key); pageContext.getOut().write(message); } catch (IOException e) { e.printStackTrace(); }
注意要导入java.nio.charset.StandardCharsets(Java 7及以上可用),如果是更早版本,直接用"UTF-8"字符串代替即可。
方案三:确保Web输出环节编码正确
另外还要确认Web容器的输出编码设置无误,比如在JSP页面开头添加:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
或者在Servlet中设置响应编码:
response.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=UTF-8");
避免ResourceBundle读取正确后,因为输出环节的编码问题再次出现乱码。
你可以优先试试方案二,这种方式最直观,不用修改资源文件内容,直接用UTF-8保存俄文或其他非ASCII字符就行。
内容的提问来源于stack exchange,提问作者Nico_99
相关产品推荐
相关产品推荐

