Jersey 2.8 client is not ignoring unknown properties during deserialization
Asked Answered
A

3

11

I am using Jersey Client 2.8 and trying to register my own Jackson configurator which will sets custom ObjectMapper properties.

public class ConnectionFactory {
   private final Client client;
   public ConnectionFactory() {
   ClientConfig clientConfig = new ClientConfig();
   clientConfig.property(ClientProperties.FOLLOW_REDIRECTS, true);
   clientConfig.property(ClientProperties.CONNECT_TIMEOUT, connTimeoutSec * 1000);
   clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeoutSec * 1000);
   this.client = ClientBuilder.newBuilder().register(JacksonConfigurator.class).register(JacksonFeature.class).withConfig(clientConfig).build();
   // Some more code here ...
   }
}

According to Example 8.15 in Jackson Registration documentation, this should register the following JacksonConfigurator class to the client.

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Provides custom configuration for jackson.
 */
@Provider
public class JacksonConfigurator implements ContextResolver<ObjectMapper> {

    private final ObjectMapper mapper;

    public JacksonConfigurator() {
        mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

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

}

If I deserialize the response from client, the client should ignore unrecognized fields in the response. But I am getting following error -

Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "xyz" (class LookupData), not marked as ignorable (3 known properties: "abc", "pqr", "def"])
 at [Source: org.glassfish.jersey.message.internal.EntityInputStream@55958273; line: 1, column: 11] (through reference chain: LookupData["xyz"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51)
    at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:731)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:915)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1292)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1270)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:247)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:118)
    at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1232)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:676)
    at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:800)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:257)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:229)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:149)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)
    ... 39 more

Can someone please let me know if I am missing something while registering the JacksonConfigurator class?

Amalle answered 15/10, 2014 at 22:38 Comment(1)
I dont have JacksonConfigurator class in my project, do I need to add one manually ?Manzano
D
20

Try initializing the Jersey client with a JacksonJsonProvider that's been configured appropriately:

final JacksonJsonProvider jacksonJsonProvider = new JacksonJaxbJsonProvider().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
final Client client = ClientBuilder.newClient(new ClientConfig(jacksonJsonProvider));

This was tested with Jackson 2.5.1 and Jersey 2.17

Drily answered 7/7, 2015 at 0:40 Comment(1)
I can approve this answer - using Jersey Client 2.22.2Aurist
S
3

I had same issue and looking for a solution... find your proposition and it works for me :)

My test is very basic / see here below :

    Client client = ClientBuilder.newClient()
            .register(JacksonFeature.class).register(JacksonConfigurator.class);


    WebTarget wt = client.target(REST_SERVICE_URL).path(
            "amount");
    wt = wt.queryParam("from", "USD");

    ConverterResponse cr=wt.request().get(ConverterResponse.class);

If I don't register your JacksonConfigurator, I get same exception as yours :

UnrecognizedPropertyException: Unrecognized field 

Because converterResponse defines a subset of REST response object methods.

Thank you very much !

Spindrift answered 2/11, 2014 at 9:1 Comment(2)
Where I can find JacksonConfigurator.class?Kooky
@Aaron, it's pasted in my questionAmalle
I
-1

Jersey version 2.30:

Exception: Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "failedLoginCount" at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@77fbf8c9; line: 1, column: 100] (through reference chain: com.xx.XXX["failedLoginCount"]) at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:62)

it works in below code:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>${jersey.version}</version>
</dependency>

import com.fasterxml.jackson.databind.DeserializationFeature;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider;


public class ServiceClient {

    private Client client;

    public ServiceClient() {
        ClientConfig config = new ClientConfig();
        JacksonJsonProvider
            jacksonJsonProvider = new JacksonJaxbJsonProvider().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        config.register(jacksonJsonProvider);

        client = ClientBuilder.newClient(config);
    }
}
Infra answered 21/5, 2020 at 16:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.