解決 i18n properties檔案中文必須是unicode的問題
阿新 • • 發佈:2018-10-31
解決 i18n properties檔案中文必須是unicode的問題
i18n unicode UTF-8目前產品需要做國際化,但 java 的 I18N 資原始檔中中文必須轉換成 unicode 才行。雖然並不會有問題,但實在是不方便,通過檢視 ResourceBundler 類的原始碼,發現其內部類 Control 在讀取資原始檔時,使用的是位元組流而非字元流。
原始碼
問題找到了,我們只要重寫 Control 類即可,使用 UTF-8 的 Reader 去讀取資原始檔即可。
詳細程式碼實現如下:
package com.feshfans.spring;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
/**
* DESC:
* CleanUser com.feshfans.spring
* feshfans 2018/5/11 18:46
* email: [email protected]
**/
public class UTF8Control extends ResourceBundle.Control {
@Override
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(new InputStreamReader(stream,"UTF-8"));
} finally {
stream.close();
}
}
} else {
throw new IllegalArgumentException("unknown format: " + format);
}
return bundle;
}
private String toResourceName0(String bundleName, String suffix) {
// application protocol check
if (bundleName.contains("://")) {
return null;
} else {
return toResourceName(bundleName, suffix);
}
}
public static void main(String[] args) {
ResourceBundle.getBundle("baseName",new UTF8Control());
}
}
然後,在構建 ResourceBundler 時,使用以下方法即可:
ResourceBundle.getBundle("baseName",new UTF8Control());