2011-01-27 7 views
13

sto usando la libreria Jackson per la serializzazione/deserializzazione da/JSON. Ho bisogno che questo JSON abbia la dimensione più piccola possibile, quindi ho abilitato la funzione ALLOW_UNQUOTED_FIELD_NAMES per eliminare tutte le virgolette. So che rimuovere le virgolette non è un errore standard, ma rendere JSON Small è un requisito fondamentale del progetto. JSON generato funziona, ma quando ho cercando di leggere il valore JSON sto diventando un'eccezione:ALLOW_UNQUOTED_FIELD_NAMES in Jackon JSON biblioteca

org.codehaus.jackson.JsonParseException: carattere imprevisto ('9' (codice 57)): aspettavo né nome valido carattere (per il nome non quotate) o doppia citazione (per citato) per avviare nome campo in [Fonte: [email protected]; line: 1, colonna: 3]

L'eccezione sopra viene generata quando ho letto questo JSON:

{90110a2e-febd-470f-afa4-cf7e890d31b9:0,eec652ad-a4d9-4eb1-8d24-7c1a0c29449f:1} 

Il modo ho letta è:

Map<String, Object> valuesMap = oM.readValue(json, new TypeReference<Map<String, Object>>() {}); 

e l'oggetto Il mapper che uso sia per leggere sia per scrivere i valori è:

private static final ObjectMapper om = new ObjectMapper(); 
static { 
    om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false); 
    om.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 
    om.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, true); 
    om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
    om.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); 
} 

Sto usando la versione 1.6.3 di Jackson, in entrambi i progetti del mittente e del destinatario. La versione necessaria per questa funzione è 1.2+, quindi ho pensato che forse non stavo usando questa versione, ma il mio ricevitore è un'applicazione Spring e ho controllato che la libreria installata nella cartella libs sia la 1.6.3.

Cosa posso fare di sbagliato? Forse questa funzione non può essere utilizzata con le mappe.

Ho un'altra domanda, Finora sto solo l'invio di una mappa in cui la chiave è solo un valore uuid e il valore è un numero. Posso avere problemi se invio un valore con caratteri speciali con la funzione ALLOW_UNQUOTED_FIELD_NAMES? Jackson sfuggirà a questi personaggi?

Grazie.

risposta

5

Sembra come Jackson QUOTE_FIELD_NAMES in alcuni casi produce tale uscita che non si può leggere anche con ALLOW_UNQUOTED_FIELD_NAMES su. Probabilmente sarà necessario implementare lo standard JsonParser per l'analisi di input non standard.

Il problema è che si sta generando JSON non standard e non c'è nessuna garanzia che il cliente si occuperà in modo corretto. Tuttavia, se non lo esponi al di fuori delle tue applicazioni e ti preoccupi delle dimensioni, potresti analizzare/generare un formato binario come quello di Jackson Smile. Vedi http://www.cowtowncoder.com/blog/archives/2010/09/entry_418.html (2.4).

+0

Ottimo punto sul sorriso: può essere compatto, specialmente quando si abilitano i riferimenti back valore stringa (se ci sono molti valori stringa ripetuti, come i valori enumerati) – StaxMan

2

Credo che il problema è legato alla sintassi Javascript e non a Jackson né JSON.

In Javascript un nome è una lettera opzionalmente seguita da una o più lettere, cifre o barre trasversali, quindi 90110a2e-febd-470f-afa4-cf7e890d31b9 non è un nome Javascript valido.

Le virgolette attorno al nome di una proprietà sono opzionali se il nome sarebbe un nome JavaScript legale e non una parola riservata. Quindi le virgolette sono obbligatorie attorno a "first-name", ma sono opzionali attorno a first_name.

BTW, se sei così preoccupato per le dimensioni JSON perché non lo stai gzip?

+0

Grazie, ci avevo pensato, ma non ero sicuro che le variabili fossero legali o meno. Sebbene json non sia usato in javascript (viene inviato da un client Java a un'applicazione JEE), ciò che dici potrebbe essere corretto. Per quanto riguarda gzip, sto già inviando il json zippato, ma grazie comunque per l'idea. – Javi

6

Ok, la risposta di Pingw33n è più o meno corretta. Quindi: sì, puoi usare la funzione; ma è piuttosto euristico - dal momento che non ci sono specifiche su come i nomi non quotati dovrebbero funzionare (dopotutto, JSON consente a qualsiasi e tutti i caratteri per i nomi!); o, se si dovesse utilizzare un meccanismo di fuga, è indovinato da chiunque su cosa dovrebbe essere scritto o accettato.

In questo caso particolare è probabilmente il carattere "-" che causa un problema. Non è una parte legale del nome Javascript, che è l'approssimazione che Jackson usa.

Una possibile soluzione sarebbe per Jackson di sfuggire a tali caratteri nei nomi delle proprietà (non ricordo come è fatto attualmente, se sono citati tutti i caratteri del nome). Se si riesce a capire un semplice caso di test, è possibile presentare una richiesta di incantesimo Jira allo Jackson Jira per ottenere l'aggiunta di escape (e assicurarsi che il parser possa rimuovere la solita versione backslash).

+1

Oh. In realtà, è ancora più semplice di così: poiché gli identificatori javascript non possono iniziare con i numeri, questo è ciò che causa il problema. Potrebbe anche essere possibile rilassarsi anche per la modalità ALLOW_UNQUOTED_FIELD_NAMES; per questo sarebbe utile una richiesta di funzionalità di Jira. – StaxMan