2013-05-04 15 views
11

Sto usando cliente Jersey JAX-RS (versione 2.0). So che sta usando un ObjectMapper di Jackson per generare e analizzare JSON. Voglio usare lo stesso oggetto per generare JSON per alcune classi java in modo che io possa scriverle in un log.Come estrarre ObjectMapper dal client JAX-RS?

so di poter creare una nuova istanza di ObjectMapper ma preferisco chiedere Jersey client di darmi un riferimento a quello che si sta usando. Come posso fare questo? Jersey 2.0 è a conoscenza di Jackson perché include una classe JacksonFeature che viene utilizzata per configurare la funzionalità di Jackson in primo luogo.

risposta

18

ho risolto questo aggiungendo i seguenti membri statici:

private static JacksonJsonProvider jackson_json_provider = new JacksonJaxbJsonProvider() 
     .configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false) 
     .configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false); 

private static ObjectMapper object_mapper = jackson_json_provider.locateMapper(
     Object.class, MediaType.APPLICATION_JSON_TYPE); 

private static Client client = ClientBuilder.newClient().register(jackson_json_provider); 

nota che la seconda dichiarazione senza jus t per configurare FAIL_ON_UNKNOWN_PROPERTIES o FAIL_ON_EMPTY_BEANS; Io uso object_mapper per altri motivi.

+0

Se si ha solo il' client', come si può estrarre 'objectMapper' da' client'? – DerekY

+0

@DerekY Non sono sicuro di come farlo. – necromancer

17

Jersey in realtà non configura esplicitamente un'istanza di ObjectMapper, ma delega a JacksonJsonProvider, che a sua volta utilizza un'istanza di mapping predefinita. Puoi risalire allo the JacksonProviderProxy code per vedere come funziona. È possibile creare e personalizzare un mapper condivisa da utilizzare in tutta l'applicazione definendo una context resolver:

@Provider 
public class ObjectMapperContextResolver implements 
     ContextResolver<ObjectMapper> { 
    private ObjectMapper mapper = null; 

    public ObjectMapperContextResolver() { 
     super(); 

     // Illustrate configuration of the mapper instance 
     mapper = new ObjectMapper().configure(
       SerializationConfig.Feature.WRAP_ROOT_VALUE, true).configure(
       DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 
    } 

    @Override 
    public ObjectMapper getContext(Class<?> type) { 
     return mapper; 
    } 
} 

Il fornitore di Jackson recupererà la sua istanza mapper da questo resolver, e si potrebbe fare lo stesso nel codice, come così :

public class MyResource { 
    @Context 
    private ContextResolver<ObjectMapper> mapperResolver; 

    public void someResourceMethod() { 
     final ObjectMapper mapper = mapperResolver.getContext(Object.class); 
    } 
} 
+0

grazie. come si confronta alle mie 3 righe di codice: 'private static JacksonJsonProvider ...' (non leggibile come commento quindi l'ho aggiunto come risposta) – necromancer

+2

anche, guardando le iniezioni di dipendenza mi chiedo se il tuo metodo funziona per il client jersey ? o solo il server della maglia? – necromancer

+1

@necromancer 'Client Client = ClientBuilder.newClient(); client.register (ObjectMapperContextResolver.class); ' – Martin

0

non era in grado di ottenere per il mapper Maglia oggetto per configurarlo, in base alle altre soluzioni qui (utilizzando Jackson 2.8.3). (Ho il sospetto che potrebbe essere correlato al container OSGi, ma comunque ...) Un modo forza bruta intorno è quello di ottenere l'oggetto Response da parte del Cliente e invocare la propria istanza di ObjectMapper su di esso. Quindi la stessa istanza può essere riutilizzata anche con la tua configurazione esplicita altrove.

Client client = ClientBuilder.newClient(); 
ObjectMapper mapper = new ObjectMapper(); 
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
... 
Response r = client.target(URL).request().get(); 
MyDtoClass dto = mapper.readValue((InputStream)(r.getEntity()), MyDtoClass.class); 
Problemi correlati