2012-05-17 13 views
12

Abbiamo un intero set di servizi REST JAX-RS in esecuzione su Apache CXF e Jackson. Usiamo le annotazioni JAXB per occuparci dei POJO di marshalling su JSON, funziona alla grande.Come passare raw JSON tramite Jackson?

Tuttavia, abbiamo uno o due punti in cui vogliamo restituire una stringa JSON non elaborata (che recuperiamo da una cache Redis).

Jackson avvolge sempre la stringa tra virgolette e sfugge a tutte le doppie virgolette, ad es.

@GET @Produces("application/json") 
public Response getData() { 

    String json = ...get from Redis... 
    return Response.ok(json,"application/json").build() 
} 

ci dà

"{\"test\":1}" 

invece di

{"test":1} 

Ho provato diverse cose, aggiungendo RawSerializer (String.class) per il mapper oggetto, non funziona nulla. L'unica cosa che funziona è se ho impostato il tipo di supporto a stringa pianura che bypassato Jackson, ma non è buona, dal momento che sto tornando il contenuto tipo sbagliato

cioè

return Response.ok(json,"text/plain").build() 

opere, ma scarsamente (tipo di contenuto errato, che rovina le app .Net WCF che ci chiamano)

+0

Ho dovuto usare invece una mappa e lasciare a Jersey l'analisi corretta ... Ho aggiunto JacksonJsonProvider con mapper.setVisibility (PropertyAccessor.FIELD, Visibility.ANY); –

risposta

0

ObjectMapper non funziona? Dovrebbe essere solo:

ObjectMapper mapper = new ObjectMapper() 
MyObj obj = MyObj(); 
...set values... 
String jsonRes = mapper.writeValueAsString(obj); 
return Response.ok(jsonRes, MediaType.APPLICATION_JSON).build(); 
+0

No. Lo converte ancora da qualche parte e la stringa viene fuori sfuggita nella risposta. –

0

In tal caso, la soluzione migliore è quella di utilizzare tipo di ritorno di String, dal momento che il problema non è con Jackson - il cui compito è quello di produrre JSON fuori di oggetti, non passano le stringhe come è - ma con JAX-RS che non è quello di chiamare Jackson. Il provider JSON con supporto Jackson predefinito passerà il valore String esattamente come è (idem per byte[]), senza alcuna elaborazione.

Per quello che vale, v'è effettivamente JsonGenerator.writeRaw() metodo pure, che permette l'incorporamento testo letterale in OutputStream, ma JAX-RS implementazioni usano ObjectMapper, non astrazioni di basso livello.

+0

Non funziona. Se restituisco String, Jackson lo scappa ancora, ad es. "{\" test \ ": 1}" –

+0

Quale versione? 2.0.2 dovrebbe funzionare in questo modo (ha avuto un problema tecnico in 2.0.0 che potrebbe essere rilevante qui); così come 1.9.x. – StaxMan

10

Finalmente trovata la soluzione. Il trucco era quello di estendere il JacksonJsonProvider (che usiamo in CXF per forzarlo ad utilizzare al posto di Jackson Jettison) e dirgli di bypassare Jackson del tutto quando si tratta di stringhe prime:

public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType){ 
    if (String.class.equals(type)) { 
     //pass strings as-is, they are most likely cached JSON responses 
     return false; 
    } else { 
     return true; 
    } 
} 

funziona perfettamente.

+0

Sto affrontando lo stesso problema ora ... Puoi fornire l'esempio di JacksonJsonProvider che ha risolto il problema, per favore? –

+0

Dove dovrei aggiungerlo ??? Ho ottenuto il mio provider registrato, ma non ancora workign ... Dec 14, 2013 8:49:11 com.sun.jersey.api.core.ScanningResourceConfig logClasses INFO: Classi di provider trovati: classe com.wordnik.swagger. jersey.listing.JerseyApiDeclarationProvider classe com.tools.web.handler.JacksonJsonProvider –

Problemi correlati