6

I'm doing a little PoC using jersey client to consume a REST service and I'm having problems with a field that is in LocalDateTime format. The REST service response is like this:

{
    "id": 12,
    "infoText": "Info 1234",
    "creationDateTime": "2001-12-12T13:40:30"
}

And my entity class:

package com.my.poc.jerseyclient;

import java.time.LocalDateTime;

public class Info {

    private Long id;
    private String infoText;
    private LocalDateTime creationDateTime;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getInfoText() {
        return infoText;
    }

    public void setInfoText(String infoText) {
        this.infoText = infoText;
    }

    public LocalDateTime getCreationDateTime() {
        return creationDateTime;
    }

    public void setCreationDateTime(LocalDateTime creationDateTime) {
        this.creationDateTime = creationDateTime;
    }

}

The dependencies in my pom.xml:

<dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.21</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-json-provider</artifactId>
            <version>2.6.1</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.6.1</version>
        </dependency>
    </dependencies>

My code doing a GET /api/info/123 with jersey client:

Client client = ClientBuilder.newClient(new ClientConfig().register(JacksonJsonProvider.class);
WebTarget webTarget = client.target("http://localhost:8080/api/").path("info/");
Response response = webTarget.path("123").request(MediaType.APPLICATION_JSON_TYPE).get();
System.out.println("GET Body (object): " + response.readEntity(Info.class));

And I'm getting an exception like this:

...
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.LocalDateTime] from String value ('2001-12-12T13:40:30'); no single-String constructor/factory method
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@21b2e768; line: 1, column: 32] (through reference chain: com.my.poc.jerseyclient.Info["creationDateTime"])
...

What am I missing? I tried this with RestTemplate (Spring rest client), and it works perfectly without any configuration.

edwise
  • 869
  • 2
  • 9
  • 18

2 Answers2

4

The jsr310 module still needs to be registered with Jackson. You can do that in a ContextResolver as seen here, where you register the Jsr310Module with the ObjectMapper

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());

You an then register the ContextResolver with the client. What will happen is that the JacksonJsonProvider should call the getContext method, and retrieve the ObjectMapper to be used for (de)serialization.

You can also use the same ContextResolver on the server side. If you only need this functionality on the client, another way is to simple construct the JacksonJsonProvider with the ObjectMapper. A little bit simpler

new JacksonJsonProvider(mapper)
Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • It works, thanks! I was thinking that I had to register it with the client in some manner, but I didn't know how. – edwise Sep 08 '15 at 11:04
1

Putting it all together for client functionality:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());

JacksonJsonProvider provider = new JacksonJsonProvider(mapper);
Client client = ClientBuilder.newClient(new ClientConfig().register(provider));
stuart
  • 136
  • 2
  • 5
  • 1
    Thanks for stating the answer so clearly and cleanly. Note that since Jackson 2.6.0 the `JSR310Module` is deprecated in favor of the `JavaTimeModule`. – Lambart Oct 01 '20 at 17:01