Est-il possible d'utiliser Jackson comme sérialiseur/marshaller pour les données JSON au lieu de JAXB lors de l'utilisation de l'API client Jersey?
Si oui, comment le configurer?
OK, je l'ai découvert, il s'avère être assez simple après tout:
ClientConfig cc = new DefaultClientConfig();
cc.getClasses().add(JacksonJsonProvider.class);
Client clientWithJacksonSerializer = Client.create(cc);
JacksonJsonProvider est issu du package jackson-jaxrs.
Vous pouvez ignorer la création d'une configuration externe et enregistrer le fournisseur directement:
Client client = ClientBuilder.newClient().register(JacksonJsonProvider.class)
Vous voudrez peut-être aussi essayer org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider (jackson-jaxrs 1.6.1)
.
JacksonJaxbJsonProvider
Pour utiliser Jackson avec une configuration personnalisée dans un client Jersey, il était courant d'utiliser JacksonJaxbJsonProvider
par exemple, comme ceci
JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
provider.setMapper(yourObjectMapper());
Client client = ClientBuilder.newClient(new ClientConfig(provider));
Malheureusement dans Jersey 2.26 ils ont copié JacksonJaxbJsonProvider
classe De com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider
artefact (Jackson) À org.glassfish.jersey.media:jersey-media-json-jackson
artefact (Jersey) Et a modifié le package De com.fasterxml.jackson.jaxrs.json
to org.glassfish.jersey.jackson.internal.jackson.jaxrs.json
.
Il est encore possible d'utiliser cette approche, il suffit simplement de modifier JacksonJaxbJsonProvider
import.
Mis à part que JacksonJaxbJsonProvider
est maintenant dans internal
, l’inconvénient du paquet est aussi Que vous devez savoir sur quelle version de Jersey le code est exécuté, ce qui peut poser problème lorsque différentes dépendances nécessitent différentes versions de Jersey.
ContextResolver<ObjectMapper>
Une meilleure possibilité de configurer Jackson dans Jersey client consiste à utiliser la même procédure que dans Jersey server , qui consiste à créer un fournisseur ObjectMapper
comme ceci:
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
private ObjectMapper objectMapper = yourObjectMapper();
@Override
public ObjectMapper getContext(Class<?> objectType) {
return objectMapper;
}
}
et l'utiliser par exemple comme ceci:
ClientConfig clientConfig = new ClientConfig();
clientConfig.register(JacksonFeature.class); // usually auto-discovered
clientConfig.register(new ObjectMapperProvider());
Client client = ClientBuilder.newClient(clientConfig);
Si vous avez à la fois le serveur et le client, vous pouvez réutiliser la classe ObjectMapperProvider
.
Il semble que cette approche fonctionne à partir de la version 2.9 de Jersey.
J'ai rencontré un problème similaire, mais pour moi, aucune des suggestions données ici ne fonctionnait. Ce qui a fonctionné pour moi était le suivant:
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
...
ClientBuilder clientBuilder = ClientBuilder.newBuilder()
clientBuilder.register(JacksonFeature.class);
...
Client client = clientBuilder.build();
Le changement clé était l'utilisation de JacksonFeature.class
- il provient de jersey-media-json-jackson-x.yy.jar
J'ai eu l'idée d'utiliser cette solution à partir de cet article - http://www.baeldung.com/jersey-jax-rs-client
Pour le maillot 2.22.2 et Jackson 2.7.2 , les dépendances sont:
dependencies {
compile("com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.7.2")
compile("org.glassfish.jersey.core:jersey-client:2.22.2")
}
Exemple de code client:
final String name = "world";
final Client client = ClientBuilder.newClient().register(JacksonJaxbJsonProvider.class);
final WebTarget target = client.target("http://localhost:8080").path("hello").path(name);
final Message message = target.request().get(Message.class);
System.out.println(message.getWelcomeMessage()); // hello world