1. 程式人生 > >解決 i18n properties檔案中文必須是unicode的問題

解決 i18n properties檔案中文必須是unicode的問題

解決 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());