Register JacksonJsonProvider using ObjectMapper + JavaTimeModule for user Jersey 2

I am trying to marshal a response containing a timestamp in ISO format:

{
...
    "time" : "2014-07-02T04:00:00.000000Z"
...
}

in the field ZonedDateTimein the domain model object. In the end, it works if I use a solution that is commented out in the following snippet. There are many similar questions on SO, but I would like to get a specific answer, what's wrong with the other approach that uses JacksonJsonProviderwith ObjectMapper + JavaTimeModule?

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        JacksonJsonProvider provider = new JacksonJsonProvider(mapper);
        Client client = ClientBuilder.newBuilder()
//                .register(new ObjectMapperContextResolver(){
//                    @Override
//                    public ObjectMapper getContext(Class<?> type) {
//                        ObjectMapper mapper = new ObjectMapper();
//                        mapper.registerModule(new JavaTimeModule());
//                        return mapper;
//                    }
//                })
                .register(provider)
                .register(JacksonFeature.class)
                .build();

Error:

javax.ws.rs.client.ResponseProcessingException: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.time.ZonedDateTime: no String-argument constructor/factory method to deserialize from String value ('2017-02-24T20:46:05.000000Z')
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@53941c2f

Project Dependencies:

compile 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.8.7'
compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.7'
compile 'com.fasterxml.jackson.core:jackson-core:2.8.7'
compile 'com.fasterxml.jackson.core:jackson-databind:2.8.7'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.8.7'
compile 'org.glassfish.jersey.core:jersey-client:2.25.1'

change

This is where deserialization happens:

CandlesResponse<BidAskCandle> candlesResponse = webTarget.request()
                .header(HttpHeaders.AUTHORIZATION,"Bearer "+token)
                .accept(MediaType.APPLICATION_JSON)
                .get(new GenericType<CandlesResponse<BidAskCandle>>(){});
+7
source share
3 answers

, , .

, , , .

jersey-media-json-jackson

, JacksonJsonProvider. JacksonFeature ( jersey-media-json-jackson), JacksonJaxbJsonProvider, , , , .

ContextResolver, JacksonJsonProvider ContextResolver ObjectMapper. . , JacksonFeature JacksonJsonProvider ( ObjectMapper), ContextResovler .

, jersey-media-json-jackson , , - , JacksonFeature. , , . :

  1. ( )
  2. jersey-media-json-jackson. Jackson jackson-jaxrs-json-provider. jersey-media-json-jackson , .
  3. , , JacksonJaxbJsonProvider JacksonJsonProvider, . JacksonFeature, , JacksonJaxbJsonProvider. , .

    , , . , , , JacksonJaxbJsonProvider. , .

+6

:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>${jackson.version}</version>
</dependency>

public WebTarget getTarget(URI uri) {
    Client client = ClientBuilder
            .newClient()
            .register(JacksonConfig.class);
    return client.target(uri);
}

@Provider
public class JacksonConfig implements ContextResolver<ObjectMapper> {

    private final ObjectMapper objectMapper;

    public JacksonConfig() {
        objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }

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

, :

public class Test {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        Model model = mapper.readValue("{\"time\" : \"2014-07-02T04:00:00.000000Z\"}", Model.class);
        System.out.println(model.getTime());
    }

}

class Model{
    private ZonedDateTime time;

    public ZonedDateTime getTime() {
        return time;
    }
    public void setTime(ZonedDateTime time) {
        this.time = time;
    }
}

, mapper.registerModule(new JavaTimeModule());. , , - mapper. , .

+1
source

Source: https://habr.com/ru/post/1670865/


All Articles