Как использовать UTF-8 в свойствах ресурса с помощью ResourceBundle
Мне нужно использовать UTF-8 в своих свойствах ресурса с помощью Java ResourceBundle
. Когда я ввожу текст непосредственно в файл свойств, он отображается как mojibake.
Мое приложение работает на Google App Engine.
Кто-нибудь может привести мне пример? Я не могу заставить это работать.
Переведено автоматически
Ответ 1
Java 9 и новее
Начиная с Java 9 файлы свойств по умолчанию кодируются как UTF-8, и использование символов, отличных от ISO-8859-1, должно работать "из коробки".
Если вы используете IDE для их редактирования, вам нужно учитывать, что в настоящее время (октябрь 2023 г.) только в IntelliJ возможно перестроить IDE для их чтения с использованием UTF-8.
Eclipse по-прежнему упорно пытается прочитать их, используя ISO-8859-1, в результате чего Mojibake отображается в редакторе файлов свойств. Вам нужно будет вернуться к использованию универсального текстового редактора для *.properties
файлов или редактировать файлы вне IDE.
Java 8 и старше
ResourceBundle#getBundle()
Используется under the covers PropertyResourceBundle
при указании .properties
файла. Это, в свою очередь, используется по умолчанию Properties#load(InputStream)
для загрузки этих файлов свойств. Согласно javadoc, они по умолчанию считываются как ISO-8859-1.
public void load(InputStream inStream) throws IOException
Считывает список свойств (пары ключей и элементов) из входного потока байтов. Входной поток имеет простой формат, ориентированный на строку, как указано в load (Reader) и предполагается, что используется кодировка символов ISO 8859-1; то есть каждый байт представляет собой один символ Latin1. Символы, написанные не латиной1, и некоторые специальные символы представлены в ключах и элементах с использованием экранирующих символов Юникода, как определено в разделе 3.3 Спецификации языка Java™.
Итак, вам нужно сохранить их как ISO-8859-1. Если у вас есть какие-либо символы за пределами диапазона ISO-8859-1, и вы не можете использовать \uXXXX
"навскидку" и поэтому вынуждены сохранять файл как UTF-8, то вам нужно будет использовать инструмент native2ascii для преобразования файла сохраненных свойств UTF-8 в файл сохраненных свойств ISO-8859-1, в котором все непокрытые символы преобразуются в формат \uXXXX
. Приведенный ниже пример преобразует файл свойств в кодировке UTF-8 text_utf8.properties
в допустимый файл свойств в кодировке ISO-8859-1 text.properties
.
native2ascii -кодировка UTF-8 text_utf8.properties text.properties
При использовании IDE, такой как Eclipse или IntelliJ, это уже выполняется автоматически, когда вы создаете .properties
файл в проекте на базе Java и используете собственный редактор файлов свойств IDE. Он прозрачно преобразует символы за пределами диапазона ISO-8859-1 в \uXXXX
формат. Смотрите также приведенные ниже скриншоты из Eclipse (обратите внимание на вкладки "Свойства" и "Исходный код" внизу, щелкните для увеличения):
В качестве альтернативы вы также можете создать пользовательскую ResourceBundle.Control
реализацию, в которой вы явно считываете файлы свойств как UTF-8 с помощью InputStreamReader
, чтобы вы могли просто сохранить их как UTF-8 без необходимости возни с native2ascii
. Вот начальный пример:
public class UTF8Control extends Control {
public ResourceBundle newBundle
(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
// The below is a copy of the default implementation.
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, "properties");
ResourceBundle bundle = null;
InputStream stream = null;
if (reload) {
URL url = loader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
} else {
stream = loader.getResourceAsStream(resourceName);
}
if (stream != null) {
try {
// Only this line is changed to make it to read properties files as UTF-8.
bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
} finally {
stream.close();
}
}
return bundle;
}
}
Это можно использовать следующим образом:
ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", new UTF8Control());
Смотрите также:
Ответ 2
Учитывая, что у вас есть экземпляр ResourceBundle, и вы можете получить строку с помощью:
String val = bundle.getString(key);
Я решил свою проблему с отображением японского языка с помощью:
return new String(val.getBytes("ISO-8859-1"), "UTF-8");
Ответ 3
посмотрите на это : http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html#load (java.io.Reader)
свойства принимают объект Reader в качестве аргументов, который вы можете создать из InputStream.
во время создания вы можете указать кодировку считывателя:
InputStreamReader isr = new InputStreamReader(stream, "UTF-8");
затем примените это средство чтения к методу загрузки :
prop.load(isr);
Кстати: получаем поток из файла .properties :
InputStream stream = this.class.getClassLoader().getResourceAsStream("a.properties");
Кстати: получить пакет ресурсов из InputStreamReader
:
ResourceBundle rb = new PropertyResourceBundle(isr);
надеюсь, это может вам помочь!
Ответ 4
Эта проблема, наконец, исправлена в Java 9: https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9
Кодировка по умолчанию для файлов свойств теперь UTF-8.
Это не должно повлиять на большинство существующих файлов свойств: UTF-8 и ISO-8859-1 имеют одинаковую кодировку символов ASCII, а читаемая человеком кодировка ISO-8859-1, отличная от ASCII, недопустима в UTF-8. При обнаружении недопустимой последовательности байтов UTF-8 среда выполнения Java автоматически перечитывает файл в ISO-8859-1.