2011-12-14 12 views
21

Mi è stato chiesto di abbellire il Jackson JSON predefinito che esce da un endpoint RestEasy. Ho fatto delle ricerche su Jackson e ho scritto del codice standalone per poter sopprimere i null, personalizzare i formati dei dati, ecc. Ora la sfida è iniettare questo codice nella serializzazione JSON di RestEasy.Accesso a Jackson Object Mapper in RestEasy

A giudicare dai post del forum questo è banale in primavera, tuttavia non sembra essere il caso in RestEasy. Ho scritto un ContextResolver e configurato come resteasy.provider nei parametri di contesto in web.xml (su Tomcat) ma questo impedisce alla webapp di caricarsi su Tomcat.

Ora sto cercando di estendere javax.ws.rs.core.Application e fornire un ContextResolver ma senza fare progressi. È così semplice, qualcuno ha fatto questo? Qualsiasi aiuto è molto apprezzato.

+0

Ok, sono stato in grado di farlo scrivendo un JacksonJsonProvider personalizzato basato sulla voce wiki.fasterxml.com/JacksonFAQJaxRs. Il codice è il seguente - – codegeek

risposta

2

Il provider per Jackson ObjectMapper dovrebbe essere un modo standard JAX-RS per farlo (funziona con Jersey), quindi sembra che sia il modo di procedere con RESTeasy.

+0

Grazie per la tua risposta, potresti approfondire su questo? Se puoi farmi sapere come stai registrando il tuo objectmapper/serializzatore/contextresolver personalizzato, sarebbe fantastico. – codegeek

+0

Questo aiuto? http://wiki.fasterxml.com/JacksonFAQJaxRs – StaxMan

+1

Ok, grazie l'ho capito .. Stavo combattendo con problemi non correlati, questo è semplice, ho scritto un JacksonJsonProvider personalizzato come segue - – codegeek

13

Ok, ho capito, ero in grado di farlo scrivendo un JacksonJsonProvider personalizzato basato sul codice di .La Jackson FAQ: JAX-RS è il seguente:

@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

Come hai "registrato" questo Provider ? –

+0

uso Dal momento che Jackson 1.8 setDateFormat() è sconsigliata mapper.getSerializationConfig(). WithDateFormat() – ozhan

+5

@DanielSerodio può essere fatto in web.xml ' resteasy.providers com.package.JsonProvider ' – thiagoh

12

Ho trovato un modo migliore di modificare il Jackson SerializationConfig - puoi intercettare la creazione di ObjectMapper usando un ContextResolver JAX-RS.

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

È necessario registrarsi presso RESTEasy in uno dei seguenti modi:

  • ritorno come una classe o istanza da un'implementazione javax.ws.rs.core.Application
  • Lista come provider con resteasy.providers
  • Lascia che RESTEasy lo scansiona automaticamente nel file WAR. . Vedere Guida alla configurazione
  • aggiungerlo manualmente tramite ResteasyProviderFactory.getInstance() registerProvider (Class) o registerProviderInstance (Object)

Riferimento: RESTEasy docs

Riferimento: Nicklas Karlsson on the JBoss forums

Si prega di notare che questo funziona con RESTEasy 2.3.2 che viene fornito come modulo in JBoss 7.1.1.Final, ma non sembra funzionare con RESTEasy 3.0-beta5.

+0

Molto bello, grazie. – Fabio

+0

Sei un risparmiatore di vita! Molte grazie! – RoyB

1

Se si sta utilizzando il provider Jackson2 è necessario fare qualcosa di leggermente diverso dalla risposta precedente. Questo esempio pretty-stampare l'output di default

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

} 

e registrarlo nel vostro web-xml, se non si dispone di autoregister su, aggiungerlo ai resteasy.providers context-param

+2

In questo modo la configurazione del mapper verrà modificata su ogni serializzazione. Come configurare il mapper una volta? Per esempio se devo registrare un modulo Jackson. Non voglio registrarlo di nuovo su ogni richiesta http. – djxak

0

Se si sta utilizzando il Jackson 2.2.x fornitore, Resteasy ha fornito un'annotazione pretty-printing simliar con quella di fornitore di JAXB:

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

Ecco un esempio:

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

Come mostra l'esempio mostrato sopra, l'annotazione @Formatted sarà abilitare l'opzione Jackson sottostante "SerializationFeature.INDENT_OUTPUT".

© RESTEasy User Guide.

Questa non è una soluzione globale, ma è possibile inserire l'annotazione anche nelle classi.

Problemi correlati