2012-05-17 12 views
12

Tenemos un conjunto completo de servicios JAX-RS REST que se ejecutan en la parte superior de Apache CXF y Jackson. Usamos anotaciones JAXB para encargarnos de organizar POJOs en JSON, funciona muy bien.¿Cómo pasar raw JSON a través de Jackson?

Sin embargo, tenemos uno o dos lugares en los que queremos devolver cadena JSON sin procesar (que recuperamos de un caché Redis).

Jackson siempre ajusta la cadena entre comillas dobles y escapa de todas las comillas dobles, p. Ej.

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

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

nos da

"{\"test\":1}" 

en lugar de

{"test":1} 

He intentado varias cosas, la adición de RawSerializer (String.class) para el mapeador de objetos, nada funciona. Lo único que funciona es si fijo el tipo de medio de cadena sencilla, que omite Jackson, pero no es bueno, ya que estoy devolviendo el contenido incorrecto tipo

es decir

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

obras, pero mal (tipo de contenido incorrecto, que daña las aplicaciones .Net WCF que nos llaman)

+0

Tuve que usar un mapa en su lugar y dejar que Jersey lo analizara correctamente ... Agregué JacksonJsonProvider con mapper.setVisibility (PropertyAccessor.FIELD, Visibility.ANY); –

Respuesta

0

¿ObjectMapper no está funcionando? Sólo debe ser:

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

No. Todavía lo convierte en algún lugar y la cadena sale escapada en la respuesta. –

0

En tal caso, lo mejor es utilizar el tipo de devolución de String, ya que el problema no es con Jackson - cuyo trabajo es producir JSON a partir de objetos, no pasar cadenas como es - pero con JAX-RS que no es para llamar a Jackson. El proveedor JSON respaldado por Jackson predeterminado pasará el valor String exactamente como está (ídem para byte[]), sin ningún procesamiento.

Por lo que vale, no es en realidad JsonGenerator.writeRaw() método, así, lo que permite la incrustación de texto literal en OutputStream, pero JAX-RS implementaciones utilizan ObjectMapper, no abstracciones de bajo nivel.

+0

No funciona. Si devuelvo String, Jackson aún lo escapa, p. "{\" test \ ": 1}" –

+0

¿Qué versión? 2.0.2 debería funcionar de esta forma (tenía un error en 2.0.0 que puede ser relevante aquí); así como 1.9.x. – StaxMan

10

Encontrado la solución finalmente. El truco consistía en extender el JacksonJsonProvider (que utilizamos en CXF para forzarlo a utilizar en lugar de Jackson Echazón) y decirle que para eludir Jackson por completo cuando se trata de Cuerdas primas:

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; 
    } 
} 

funciona perfectamente.

+0

Estoy enfrentando el mismo problema ahora ... ¿Pueden darnos el ejemplo de JacksonJsonProvider que resolvió el problema, por favor? –

+0

¿Dónde debería agregarlo ??? Conseguí que mi proveedor se registrara, pero no firmó todavía ... Dec 14, 2013 8:49:11 AM com.sun.jersey.api.core.ScanningResourceConfig logClasses INFORMACIÓN: Clases de proveedores encontradas: clase com.wordnik.swagger. jersey.listing.JerseyApiDeclarationProvider clase com.tools.web.handler.JacksonJsonProvider –

Cuestiones relacionadas