Pergunta

É possível usar Jackson como serializador/marshaller para dados JSON em vez de JAXB ao usar a API do cliente Jersey?

Se sim, como configurá -lo?

Foi útil?

Solução

Ok, eu descobri, acaba sendo bastante simples, afinal:

ClientConfig cc = new DefaultClientConfig();
cc.getClasses().add(JacksonJsonProvider.class);
Client clientWithJacksonSerializer = Client.create(cc);

O JacksonjsonProvider vem do pacote Jackson-Jaxrs.

Outras dicas

Você pode pular a criação de configuração externa e registrar o provedor diretamente:

Client client = ClientBuilder.newClient().register(JacksonJsonProvider.class)

Solução com JacksonJaxbJsonProvider

Maneira comum de como usar Jackson com configuração personalizada no cliente Jersey era usar JacksonJaxbJsonProvider por exemplo, assim

JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
provider.setMapper(yourObjectMapper());
Client client = ClientBuilder.newClient(new ClientConfig(provider));

Infelizmente em Jersey 2.26 Eles copiaram JacksonJaxbJsonProvider classe de com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider artefato (Jackson) para org.glassfish.jersey.media:jersey-media-json-jackson artefato (Jersey) e pacote alterado de com.fasterxml.jackson.jaxrs.jsonpara org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.

Ainda é possível usar essa abordagem, é necessário mudar JacksonJaxbJsonProvider importar.

Além de JacksonJaxbJsonProvider estar agora em internal A desvantagem do pacote também é que você deve saber em qual versão da camisa seu código é executado, o que pode ser um problema quando diferentes dependências exigem versões de camisa diferentes.

Melhor solução com ContextResolver<ObjectMapper>

Melhor possibilidade de como configurar Jackson em Jersey cliente é usar da mesma maneira que é configurado em Jersey servidor o que é criar ObjectMapper provedor como este:

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {

    private ObjectMapper objectMapper = yourObjectMapper();

    @Override
    public ObjectMapper getContext(Class<?> objectType) {
        return objectMapper;
    }

}

e use -o, por exemplo, como este:

ClientConfig clientConfig = new ClientConfig();
clientConfig.register(JacksonFeature.class);  // usually auto-discovered
clientConfig.register(new ObjectMapperProvider());
Client client = ClientBuilder.newClient(clientConfig);

Se você possui o servidor e o cliente, pode reutilizar ObjectMapperProvider classe.

Parece que essa abordagem funciona a partir da Jersey versão 2.9.

Você também pode querer tentar org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider (jackson-jaxrs 1.6.1).

Eu encontrei uma questão semelhante, mas para mim nenhuma das sugestões dadas aqui funcionou. O que funcionou para mim estava abaixo da parte do código:

import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
...

ClientBuilder clientBuilder = ClientBuilder.newBuilder()
clientBuilder.register(JacksonFeature.class);
...
Client client = clientBuilder.build();

A principal mudança foi o uso de JacksonFeature.class - vem de jersey-media-json-jackson-x.yy.jar

Eu tenho pista para usar esta solução deste artigo - http://www.baeldung.com/jersey-jax-rs-client

Para Jersey 2.22.2 e Jackson 2.7.2 As dependências gradle são:

dependencies {
    compile("com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.7.2")
    compile("org.glassfish.jersey.core:jersey-client:2.22.2")
}

Exemplo de código do cliente é:

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top