Post@https://ryan-miao.github.io
背景
还是多语言, 在项目中遇到本地环境和服务端环境不一致乱码的情形。因此需要搞清楚乱码产生的过程,来分析原因。
获取多语言代码如下:
private Map<String, String> getLocalizationContent(Locale locale) {
ResourceBundle bundle = ResourceBundle.getBundle(this.resourceBundleName, Locale.US);
ResourceBundle bundleLocale = ResourceBundle.getBundle(this.resourceBundleName, locale);
Set<String> keys = bundle.keySet();
Map<String, String> map = new HashMap();
String key;
String translation;
for(Iterator var6 = keys.iterator(); var6.hasNext(); map.put(key, translation)) {
key = (String)var6.next();
try {
translation = bundleLocale.getString(key);
translation = new String(translation.getBytes("ISO-8859-1"), "UTF-8");
translation = this.escapeStringForJavaScript(translation);
} catch (UnsupportedEncodingException | MissingResourceException var10) {
translation = bundle.getString(key);
}
}
return map;
}
其中,因为ResourceBundle
通过PropertyResourceBundle
读取properties
文件。 这就要看以哪种方式load Properties了。提供了两种构造函数:
public PropertyResourceBundle (InputStream stream) throws IOException {
Properties properties = new Properties();
properties.load(stream);
lookup = new HashMap(properties);
}
public PropertyResourceBundle (Reader reader) throws IOException {
Properties properties = new Properties();
properties.load(reader);
lookup = new HashMap(properties);
}
通过跟踪ResourceBundle.getBundle(this.resourceBundleName, locale);
源码发现创建bundle的方法为:
public ResourceBundle newBundle(String baseName, Locale locale, String format,
ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
String bundleName = toBundleName(baseName, locale);
ResourceBundle bundle = null;
if (format.equals("java.class")) {
try {
@SuppressWarnings("unchecked")
Class<? extends ResourceBundle> bundleClass
= (Class<? extends ResourceBundle>)loader.loadClass(bundleName);
// If the class isn't a ResourceBundle subclass, throw a
// ClassCastException.
if (ResourceBundle.class.isAssignableFrom(bundleClass)) {
bundle = bundleClass.newInstance();
} else {
throw new ClassCastException(bundleClass.getName()
+ " cannot be cast to ResourceBundle");
}
} catch (ClassNotFoundException e) {
}
} else if (format.equals("java.properties")) {
final String resourceName = toResourceName0(bundleName, "properties");
if (resourceName == null) {
return bundle;
}
final ClassLoader classLoader = loader;
final boolean reloadFlag = reload;
InputStream stream = null;
try {
stream = AccessController.doPrivileged(
new PrivilegedExceptionAction<InputStream>() {
public InputStream run() throws IOException {
InputStream is = null;
if (reloadFlag) {
URL url = classLoader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
// Disable caches to get fresh data for
// reloading.
connection.setUseCaches(false);
is = connection.getInputStream();
}
}
} else {
is = classLoader.getResourceAsStream(resourceName);
}
return is;
}
});
} catch (PrivilegedActionException e) {
throw (IOException) e.getException();
}
if (stream != null) {
try {
bundle = new PropertyResourceBundle(stream);
} finally {
stream.close();
}
}
} else {
throw new IllegalArgumentException("unknown format: " + format);
}
return bundle;
}
也就是说,最终通过pr