Кодировка символов Java, преобразование ISO в UTF

Эта тема была предметом обсуждения во многих дискуссиях, но мы все еще видим новые. Мой сценарий выглядит следующим образом:

Среда Java, работающая на сервере Linux, где UTF-8 является кодировкой символов по умолчанию в JVM. Структура состоит из некоторых служб, получающих сообщения Tibco RV для обработки. И некоторые из этих сообщений содержат символы, отличные от ASCII, и отправляются с сервера Windows, а ISO8859-1 - это кодировка, используемая при создании сообщения. Теперь, когда данные извлекаются из сообщения Tib rv, проблемные поля "прибывают" как объекты Java и должны быть преобразованы в строки... И здесь я еще не смог извлечь строки ISO8859-1, содержащие не Символы ASCII (шведский "å","ä","ö") в строке UTF-8 надлежащим образом. Я пытался с помощью следующих методов:

String isoStreet = new String(response.get("street").toString().getBytes(StandardCharsets.ISO_8859_1),java.nio.charset.StandardCharsets.UTF_8);

и я также попытался использовать кодировщики / декодеры в пакете java.nio безуспешно.

Также интересно то, что я использую PuttY для подключения к серверу, где сервисы размещаются и работают. И оттуда у меня есть возможность сделать прямой запрос Tibco rv из оболочки (используя клиент tibcorvsend), и мне кажется, что мне нужно установить удаленный набор символов ISO8859-1 в PuttY (Window_>Translation) перед входом в сервер и сделайте этот запрос Tib rv - когда это будет сделано, в ответе будут указаны правильные символы без ASCII, независимо от того, какую кодировку я установил на удаленном сервере Linux. Использование 'export LC_ALL=en_US.UTF-8' или 'export LC_ALL=sv_SE.iso88591' в этом случае не имеет значения... только то, какую удаленную кодировку я установил в PuttY...

Это должно означать, что ответное сообщение выглядит нормально и, по крайней мере, оболочка способна выводить правильные символы. Но когда внутри Java VM (с использованием Java-сервисов), я предполагаю, что поля ответа незаметно помещаются в Strings при отладке и просмотре объекта ответа (не желая этого преобразования в Strings) в представлении Watch... не уверен, что вы могли бы следовать за мной в этом Если нет, я могу попытаться быть более ясным, если это необходимо...

Любой вклад по этой проблеме, любой

С уважением /R

1 ответ

Кодировка символов определяет, как текст, состоящий из символов, переводится в байты и наоборот. Как вы знаете, существуют разные кодировки символов, такие как ASCII, ISO-8859-1 и UTF-8.

Строка состоит из символов. В какой-то момент вы хотите преобразовать эти символы в байты, чтобы вы могли отправлять их по сети, сохранять их в файле или как угодно. Вы используете кодировку символов для перевода строки в байты. А с другой стороны, где вы получаете байты, вы используете ту же кодировку символов для перевода байтов обратно в символы в строке.

Давайте посмотрим, почему строка, подобная той, которую вы разместили, неверна. Давайте сначала перепишем это так, чтобы я мог объяснить части:

String street = response.get("street").toString();
byte[] streetBytes = street.getBytes(StandardCharsets.ISO_8859_1);
String isoStreet = new String(streetBytes, StandardCharsets.UTF_8);

В первой строке вы получаете данные из ответа и конвертируете их в строку. (Что значит response.get("street") вернуть?).

Во второй строке вы кодируете эту строку, используя набор символов ISO-8859-1. Вы получаете байтовый массив, который содержит действительные коды символов ISO-8859-1 для символов в строке.

В третьей строке вы конвертируете байты в строку и делаете вид, что байты являются байтами UTF-8. Это, очевидно, неправильно, поскольку байты являются данными ISO-8859-1, а не данными UTF-8. Когда вы делаете это, вы можете получить неправильные символы или даже исключение, если байтовый массив содержит последовательность байтов, которая не является допустимым символом в соответствии с UTF-8.

Следует помнить, что строка состоит только из символов. Строка сама по себе не имеет кодировки. Вы используете кодировку символов для перевода строки в байты и наоборот. Вы не можете "изменить кодировку символов строки", потому что кодировка символов просто не является свойством строки. Также как число не является по сути десятичным или шестнадцатеричным - это просто разные способы представления одного и того же числа.

Что вам нужно сделать, это:

  • В точке, где вы пишете сообщение, убедитесь, что вы используете правильную кодировку символов для преобразования строк в байты.

  • В месте, где вы читаете сообщение, убедитесь, что вы используете правильную кодировку символов для преобразования байтов в строки.

Не читайте что-либо в строку, используя кодировку по умолчанию для платформы, а затем попытайтесь "преобразовать строку". Это не работает.

Другие вопросы по тегам