Вопрос-ответ

How to use UTF-8 in resource properties with ResourceBundle

Как использовать 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.


2024-02-06 04:35 java