GSON / JSON: странный выпуск специального символа (умляута) - PullRequest
5 голосов
/ 24 октября 2011

При попытке обработать ответ JSON с помощью GSON (в случае запроса вы получаете API flickr), я столкнулся с довольно странным кодированием некоторых специальных символов:

Original JSON response

Вот его шестнадцатеричное представление:

Hex View of Original JSON response

«u», за которым следуют «двойные точки», это то, что должно быть немецким«ü», и вот тут начинается мое замешательство.Это как если бы кто-то взял символ и разорвал его пополам, кодируя каждую из двух частей.На следующем рисунке показано шестнадцатеричное кодирование того, что я ожидал, если бы 'ü' было правильно закодировано:

Expected Hex View

Еще более странно, в тех случаях, когда яожидать возникновения проблем (а именно, азиатский набор символов) все работает нормально, например "title": "ナ ガ レ テ ユ ク ・ ・ ・"

Вопросы:

  1. Это какой-то flickrAPIСтранность или правильная кодировка JSON для отката?Или это довольно правильно закодированный JSON, и это GSON, который не может «собрать» этот ответ в исходное «ü».Или же автор заглавного сообщения просто прикрутил его к своей части?
  2. Как мне решить проблему (в случае, если это либо JSON, либо GSON, которые возятся, очевидно, ничего не могут сделать, если это был автор).Как я узнаю, какие «другие» символы затронуты (ö и ä приходят на ум, но, возможно, есть и более «особые случаи»).

1 Ответ

5 голосов
/ 12 мая 2012

То, что вы видите, это случай декомпозиции Unicode :

Символы, такие как немецкие умляуты, могут быть выражены двумя способами:

  • чем большетрадиционная предварительно составленная форма в виде одного символа ü или
  • в разложенной форме в виде базового символа u, за которым следует комбинирующий диарез ̈_ (мне пришлось использовать подчеркивание здесь, чтобы сделатьон появляется потому, что он не должен стоять в одиночестве, это просто "зависшие точки")

Если вы получите что-то подобное, его легко конвертировать в предварительно составленную форму с помощью java.text.Normalizer (доступно с Java 1.6):

String decomposed = "Mitgef\u0308hl";
printChars(decomposed); // Mitgefühl -- [M, i, t, g, e, f, u, ̈, h, l]
String precomposed = Normalizer.normalize(decomposed, Form.NFC);
printChars(precomposed); // Mitgefühl -- [M, i, t, g, e, f, ü, h, l]

// Normalizing with NFC again doesn't hurt:
String precomposedAgain = Normalizer.normalize(precomposed, Form.NFC);
printChars(precomposedAgain); // Mitgefühl -- [M, i, t, g, e, f, ü, h, l]
...

static void printChars(String s) {
  System.out.println(s + " -- " + Arrays.toString(s.toCharArray()));
}

Как видите, применение NFC к уже предварительно составленной строке не повредит.

Примечаниечто печать String будет выглядеть правильно на любом терминале с поддержкой Unicode, только если вы печатаете массив символов, вы видите разницу между разложенной и предварительно составленной формой.

Возможным источником может быть MacOS, который стремитсяхотя для кодирования вещей в разложенном виде любопытно, что Flickr не нормализует эти вещи.

...