2013-05-04 7 views
11

Ich benutze Jersey JAX-RS Client (Version 2.0). Ich weiß, dass es einen Jackson ObjectMapper verwendet, um JSON zu generieren und zu analysieren. Ich möchte dasselbe Objekt verwenden, um JSON für einige Java-Klassen zu generieren, damit ich sie in ein Protokoll schreiben kann.Wie man ObjectMapper von JAX-RS Client extrahiert?

Ich weiß, dass ich eine neue Instanz von ObjectMapper erstellen kann, aber ich möchte Jersey Client bitten, mir einen Verweis auf den zu geben, den es verwendet. Wie kann ich das machen? Jersey 2.0 kennt Jackson, weil es eine JacksonFeature-Klasse enthält, die zum Konfigurieren des Jackson-Features verwendet wird.

Antwort

18

ich löste dies durch die folgenden statischen Mitglieder ergänzt:

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

Beachten Sie, dass die zweite Erklärung jus nicht benötigt wird, t zu konfigurieren FAIL_ON_UNKNOWN_PROPERTIES oder FAIL_ON_EMPTY_BEANS; Ich verwende object_mapper aus anderen Gründen.

+0

Wenn Sie nur' client' haben, wie können Sie 'objectMapper' aus' client' extrahieren? – DerekY

+0

@DerekY Ich bin mir nicht sicher, wie das geht. – necromancer

17

Jersey konfiguriert eine ObjectMapper-Instanz nicht explizit, sondern delegiert an JacksonJsonProvider, die wiederum eine Standard-Mapper-Instanz verwendet. Sie können durch the JacksonProviderProxy code verfolgen, um zu sehen, wie es funktioniert. Sie können einen freigegebenen Mapper erstellen und anpassen, indem Sie definieren eine context resolver die gesamte Anwendung verwendet werden:

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

Der Jackson-Anbieter wird seine Mapper-Instanz aus diesem Resolver abrufen, und Sie könnten das gleiche in Ihrem Code tun, als so :

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

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

danke. Wie vergleicht dies meine 3 Zeilen Code: 'private statische JacksonJsonProvider ...' (nicht als Kommentar lesbar, so habe ich es als Antwort hinzugefügt) – necromancer

+2

auch, mit Blick auf die Abhängigkeit Injektionen Ich frage mich, ob Ihre Methode für Jersey-Client arbeiten ? oder nur Jersey-Server? – necromancer

+1

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

0

Konnte nicht zum jersey object mapper, um es zu konfigurieren, basierend auf den anderen Lösungen hier (mit jackson 2.8.3). (Ich vermute, dass es mit osgi container in Verbindung steht, aber nichtsdestoweniger ...) Eine Brute-Force-Methode ist es, das Response-Objekt vom Client zu holen und eine eigene Instanz von ObjectMapper darauf aufzurufen. Dann kann dieselbe Instanz auch an anderer Stelle mit Ihrer expliziten Konfiguration wiederverwendet werden.

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); 
Verwandte Themen