Sto cercando di includere JSON non elaborato all'interno di un oggetto Java quando l'oggetto è (de) serializzato usando Jackson. Per testare questa funzionalità, ho scritto il seguente test:Come posso includere JSON non elaborato in un oggetto usando Jackson?
public static class Pojo {
public String foo;
@JsonRawValue
public String bar;
}
@Test
public void test() throws JsonGenerationException, JsonMappingException, IOException {
String foo = "one";
String bar = "{\"A\":false}";
Pojo pojo = new Pojo();
pojo.foo = foo;
pojo.bar = bar;
String json = "{\"foo\":\"" + foo + "\",\"bar\":" + bar + "}";
ObjectMapper objectMapper = new ObjectMapper();
String output = objectMapper.writeValueAsString(pojo);
System.out.println(output);
assertEquals(json, output);
Pojo deserialized = objectMapper.readValue(output, Pojo.class);
assertEquals(foo, deserialized.foo);
assertEquals(bar, deserialized.bar);
}
Il codice emette la seguente riga:
{"foo":"one","bar":{"A":false}}
Il JSON è esattamente come voglio cose da cercare. Sfortunatamente, il codice fallisce con un'eccezione quando si tenta di leggere di nuovo il JSON nell'oggetto. Qui è l'eccezione:
org.codehaus.jackson.map.JsonMappingException: Impossibile deserializzare istanza di java.lang.String fuori START_OBJECT gettone in [Fonte: [email protected]; line: 1, colonna: 13] (attraverso la catena di riferimento: com.tnal.prism.cobalt.gather.testing.Pojo [ "barra"])
Perché la funzione Jackson bene in una direzione ma sicuro quando andando nella direzione opposta? Sembra che dovrebbe essere in grado di prendere di nuovo il proprio output come input. So che quello che sto cercando di fare è poco ortodosso (il consiglio generale è di creare un oggetto interno per bar
che abbia una proprietà denominata A
), ma non voglio affatto interagire con questo JSON. Il mio codice funge da pass-through per questo codice: voglio prendere questo JSON e inviarlo di nuovo senza toccare nulla, perché quando cambia il JSON non voglio che il mio codice abbia bisogno di modifiche.
Grazie per il consiglio.
MODIFICA: ha reso Pojo una classe statica, che causava un errore diverso.
Funziona come un fascino; vedi la mia risposta per il codice (_formatting nei commenti è awgul_). –
Ho avuto un caso d'uso diverso per questo. Sembra che se non vogliamo generare molta spazzatura di stringa nel deser/ser, dovremmo essere in grado di passare semplicemente una stringa in quanto tale. Ho visto un thread che ha tracciato questo, ma sembra che non ci sia supporto nativo possibile. Dai un'occhiata a http://markmail.org/message/qjncoohoalre4vd2#query:+page:1+mid:6ol54pw3zsr4jbhr+state:results – Sid
@Sid non c'è modo di farlo e la tokenizzazione sia in modo efficiente. Supportare il pass-through di token non processati richiederebbe un ulteriore mantenimento dello stato, il che rende l'analisi "regolare" un po 'meno efficiente. È un po 'come l'ottimizzazione tra il codice normale e il lancio di eccezioni: per supportare quest'ultimo aggiunge un sovraccarico per il precedente. Jackson non è stato progettato per cercare di mantenere disponibili gli input non elaborati; sarebbe bello averlo (anche per i messaggi di errore) in giro, ma richiederebbe un approccio diverso. – StaxMan