2015-02-02 7 views
5

Mi piacerebbe leggere un "albero" JSON da una matrice di byte java e scrivere un "albero" JSON come array di java byte usando Jackson. Un modo per farlo è la seguente:Modo consigliato corrente per convertire il byte [] in JsonNode e ritorno

ObjectMapper om = new ObjectMapper(); 
JsonNode old = om.createObjectNode(); 

byte[] arr = om.writeValueAsBytes(old); 
JsonNode new = om.readTree(arr); 

Tuttavia, Jackson in questi giorni raccomanda l'uso di ObjectReader e ObjectWriter invece di ObjectMapper, a causa della sicurezza dei thread in configurazione, ma anche a causa di ottimizzazioni che potrebbero essere rilevanti per loro solo. Ma ObjectReader non supporta direttamente readTree con gli array di byte e writeValueAsBytes è più generico di writeTree, quindi potrebbe esserci un modo (e un motivo) per ignorare la logica di mappatura dei tipi in qualche modo.

Quindi, oggi, con il più recente Jackson (2.5), qual è il modo più veloce/migliore/consigliato per eseguire queste due conversioni?

risposta

5

Il problema con l'utilizzo di ObjectMapper è che se si modifica la configurazione del programma di mappatura può causare problemi. Tuttavia, se non si modifica la configurazione sottostante, si dovrebbe comunque essere sicuri (ulteriori informazioni su here).

Ma se si utilizza ObjectReader e ObjectWriter si è completamente al sicuro, anche se effettivamente si altera la configurazione del programma di mappatura. Questo è possibile poiché il lettore/scrittore è immutabile e non è quindi possibile modificare lo stato sottostante.

Quindi, per leggere/scrivere byte il seguente approccio funziona bene:

ObjectMapper om = new ObjectMapper(); 
JsonNode oldNode = om.createObjectNode(); 

// Writing... 
// Create an immutable writer (in this case using the default settings) 
final ObjectWriter writer = om.writer(); 

// Use the writer for thread safe access. 
final byte[] bytes = writer.writeValueAsBytes(oldNode); 


// Reading... 
// Create an immutable reader 
final ObjectReader reader = om.reader(); 

// Use the reader for thread safe access 
final JsonNode newNode = reader.readTree(new ByteArrayInputStream(bytes)); 

Quindi, in pratica è possibile utilizzare gli stessi principi (con i flussi di byte), ma se avete bisogno di essere sicuri che si sono utilizzando l'accesso sicuro al mapper è necessario accedere alla lettura/scrittura tramite ObjectReader e ObjectWriter.

Il writeValueAsBytes è descritto in questo modo in the JavaDoc:

funzionalmente equivalente a chiamare writeValue(Writer,Object) con java.io.ByteArrayOutputStream e ottenere byte, ma più efficiente.

Per la lettura è sufficiente utilizzare la versione readTree(InputStream).

+0

Puoi testimoniare che l'utilizzo di ByteArrayInputStream è efficiente come readTree con byte []? Per loro, JsonFactory.createParser (byte []) deve essere efficiente quanto JsonFactory.createParser (InputStream) e dubito che lo sia - ma potrei sbagliarmi. – Nakedible

+1

@Nakedible, posso facilmente dire che non testimonierò mai in una questione del genere;) Tuttavia, ho fatto alcuni semplici [benchmark delle prestazioni] (http://hastebin.com/eberuputon.avrasm) dove ho confrontato i diversi metodi e il l'output può essere [trovato qui] (http://hastebin.com/iyiseripol.profile). – wassgren

+1

Ok, mi hai convinto, anche se i microbenchmark mentono sempre;) Grazie, ottima risposta! – Nakedible