2011-12-14 20 views
21

Se me ha pedido que embellezca Jackson JSON predeterminado que sale de un punto final RestEasy. Hice algunas investigaciones sobre Jackson y escribí un código independiente para poder suprimir nulos, personalizar formatos de datos, etc. Ahora el desafío es inyectar este código en la serialización JSON de RestEasy.Accediendo a Jackson Object Mapper en RestEasy

A juzgar por las publicaciones en el foro, esto es trivial en Spring, sin embargo, no parece ser el caso en RestEasy. Escribí un ContextResolver y lo configuré como resteasy.provider en los parámetros de contexto en web.xml (en Tomcat) pero eso impide que la aplicación webapp se cargue en Tomcat.

Ahora estoy tratando de extender javax.ws.rs.core.Application y proporcionar un ContextResolver pero sin progreso. ¿Es esto sencillo, alguien ha hecho esto? Cualquier ayuda es muy apreciada.

+0

Ok, pude hacer esto escribiendo un JacksonJsonProvider personalizado basado en la entrada wiki.fasterxml.com/JacksonFAQJaxRs. El código es el siguiente - – codegeek

Respuesta

2

El proveedor de Jackson ObjectMapper debe ser la forma estándar de JAX-RS de hacerlo (funciona con Jersey), por lo que también parece ser el camino a seguir con RESTeasy.

+0

Gracias por su respuesta, ¿podrían dar más detalles sobre esto? Si me puedes decir cómo estás registrando tu objectmapper/serializer/contextresolver personalizado, etc., sería genial. – codegeek

+0

¿Esto ayudaría? http://wiki.fasterxml.com/JacksonFAQJaxRs – StaxMan

+1

Ok, gracias, lo descubrí ... Estaba luchando con problemas no relacionados, esto es sencillo, escribí un JacksonJsonProvider personalizado de la siguiente manera: – codegeek

13

Ok, lo he descubierto, que era capaz de hacer esto escribiendo un JacksonJsonProvider personalizado basado en el código .El Jackson FAQ: JAX-RS es el siguiente:

@Provider 
public class QBOJacksonJsonProvider extends JacksonJsonProvider { 
    public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; 

    @Override 
    public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { 
     Log.info(getClass(), "In custom JSON provider"); 
     //get the Object Mapper 
     ObjectMapper mapper = locateMapper(type, mediaType); 
     // Suppress null properties in JSON output 
     mapper.getSerializationConfig().setSerializationInclusion(org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL); 
     // Set human readable date format 
     SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); 
     mapper.getSerializationConfig().setDateFormat(sdf); 

     super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream); 
    } 
} 
+9

¿Cómo "registraste" este proveedor? ? –

+0

uso Desde Jackson 1,8 setDateFormat() está en desuso mapper.getSerializationConfig(). WithDateFormat() – ozhan

+5

@DanielSerodio puede hacerse en web.xml ' resteasy.providers com.package.JsonProvider ' – thiagoh

12

he encontrado una manera más agradable de la modificación de los Jackson SerializationConfig - Puede interceptar la creación de ObjectMapper utilizando un JAX-RS ContextResolver.

@Provider 
@Produces(Array(MediaType.APPLICATION_JSON)) 
class JacksonConfig extends ContextResolver[ObjectMapper] { 

    val mapper = new ObjectMapper() 
    mapper.getSerializationConfig.setSerializationInclusion(Inclusion.NON_NULL) 

    def getContext(objectType: Class[_]) = mapper 
} 

Usted tendrá que registrarse con RESTEasy en una de las siguientes maneras:

  • devolverlo como una clase o una instancia de una aplicación javax.ws.rs.core.Application
  • Lista como proveedor con resteasy.providers
  • Deje que RESTEasy lo busque automáticamente dentro de su archivo WAR. . Ver Guía de configuración
  • agregarla manualmente a través de ResteasyProviderFactory.getInstance() registerProvider (Clase) o registerProviderInstance (Objeto)

Referencia: RESTEasy docs

Referencia: Nicklas Karlsson on the JBoss forums

Tenga en cuenta que esto funciona con RESTEasy 2.3.2 que se envía como un módulo en JBoss 7.1.1.Final, pero no parece funcionar con RESTEasy 3.0-beta5.

+0

Muy bien, gracias. – Fabio

+0

¡Eres un salvavidas! ¡Muchas gracias! – RoyB

1

Si está usando el proveedor Jackson2, necesita hacer algo ligeramente diferente de la respuesta anterior. Este ejemplo bastante-imprimir la salida por defecto

@Provider 
public class JSONProvider extends ResteasyJackson2Provider { 

    @Override 
    public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType json, MultivaluedMap<String, Object> headers, OutputStream body) throws IOException { 

    ObjectMapper mapper = locateMapper(type, json); 
    mapper.enable(SerializationFeature.INDENT_OUTPUT); 

    super.writeTo(value, type, genericType, annotations, json, headers, body); 
    } 

} 

y para registrarse en su web en XML, si no se tiene en autoregister, añadirlo a sus resteasy.providers context-param

+2

Pero de esta manera la configuración del asignador se cambiará en cada serialización. ¿Cómo configurar Mapper una vez? Por ejemplo, si necesito registrar un Módulo Jackson. No quiero volver a registrarlo en cada solicitud HTTP. – djxak

0

Si está utilizando el Jackson 2.2.x proveedor, Resteasy ha proporcionado una anotación bastante-impresión simliar con el de proveedor de JAXB:

org.jboss.resteasy.annotations.providers.jackson.Formatted 

Aquí es un ejemplo:

@GET 
@Produces("application/json") 
@Path("/formatted/{id}") 
@Formatted 
public Product getFormattedProduct() 
{ 
    return new Product(333, "robot"); 
} 

Como el ejemplo mostrado anteriormente, la anotación @Formatted se habilite la opción subyacente de Jackson "SerializationFeature.INDENT_OUTPUT".

© RESTEasy User Guide.

Esto no es una solución global, pero puede poner la anotación en las clases también.