2011-10-24 9 views
5

Durante il tentativo di elaborare una risposta JSON con GSON (l'output proviene dall'API di flickr nel caso in cui lo si stia chiedendo) ho incontrato quello che descrivevo come una codifica piuttosto strana di alcuni caratteri speciali:GSON/JSON: problema speciale di char (umlaut)

Original JSON response

Ecco una vista esadecimale di esso:

Hex View of Original JSON response

La 'U' seguito dal 'doppio-punti' è ciò che si suppone essere un tedesco ' ü ', e questo è dove la mia confusione inizia. È come se qualcuno prendesse il carattere e lo strappasse a metà, codificando ciascuno dei 2 pezzi. L'immagine seguente mostra la codifica esadecimale di quello che ci si aspetta che sia nel caso del 'ü' stato codificato correttamente:

Expected Hex View

Ancora più strano, nei casi in cui mi aspetterei problemi a verificarsi (cioè , il set di caratteri asiatici) tutto sembra funzionare bene, ad es "Title": "ナ ガ レ テ ユ ク · · ·"

Domande:

  1. è che alcune stranezza flickrAPI o la codifica JSON corretto per il reposonse? O è piuttosto codificato correttamente JSON ed è GSON che non riesce a "riassemblare" questa risposta nell'originale "ü". O l'autore del messaggio del titolo l'ha semplicemente fatto a pezzi?
  2. Come risolvo il problema (nel caso in cui sia JSON o GSON che sta facendo casino, non può ovviamente fare nulla se fosse l'autore). Come faccio a sapere quali "altri" caratteri sono interessati (mi vengono in mente, ma probabilmente ci sono più "casi speciali").

risposta

4

quello che stai vedendo c'è un caso di Unicode decomposition:

Personaggi come dieresi tedesche possono essere espressi in due modi:

  • forma precomposto più tradizionale come un singolo carattere ü o
  • in forma scomposta come carattere di base u seguito da un combining diaeresis̈_ (Ho dovuto usare un trattino basso qui per farlo apparire perché non è suppos Ed a stare da sola, è in realtà solo i "puntini si aggirano" per)

Se si riceve qualcosa come questo, è facilmente convertito in forma precomposto utilizzando java.text.Normalizer (disponibili dal 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())); 
} 

Come si può vedere, l'applicazione di NFC a una stringa già precomposta non danneggia.

Nota che la stampa del String apparirà correttamente su qualsiasi terminale con capacità Unicode, solo se si stampa l'array di caratteri si vede la differenza tra la forma decomposta e quella precomposta.

Una possibile fonte potrebbe essere MacOS che tende a codificare le cose in forma decomposta, è curioso che Flickr non normalizzi questa roba, però.

+0

Il downlocoter può spiegare perché? –