How to use some Jackson Deserializer in own custom Deserializer?
Asked Answered
V

2

4

I am struggling with mentioned in the question issue.

I need to create some custom deserializer which is more or less type conversion from the standard deserializer (reason is that ZonedDateTime is working for my input, but I don't want to change the type to ZonedDateTime, but keep LocalDateTime).

Bascially what I want to do in my deserializer is to:

  1. Deserialize using ZonedDateTime deserializer (which I found, in reality, is custom InstantDeserializer )
  2. Use .toLocalDateTime and return it.

How can I use it? Was trying to find it but I can't.

Vacation answered 5/7, 2017 at 5:58 Comment(0)
D
4

@JsonDeserialize is used to indicate the use of a custom deserializer

public class Event {
    public String name;
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime date;
}

And the custom deserializer is as follows:

public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
    @Override
    public LocalDateTime deserialize(JsonParser jsonparser, DeserializationContext context)
            throws IOException, JsonProcessingException {
        String date = jsonparser.getText();

        JavaTimeModule javaTimeModule = new JavaTimeModule();
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(javaTimeModule);
        ZonedDateTime zonedDateTime = mapper.readValue(date, ZonedDateTime.class);
        return zonedDateTime.toLocalDateTime();
    }
}

The demo can be accessed in github

Maven dependency

<dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.8.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.8.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310 -->
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.8.9</version>
        </dependency>

    </dependencies>
Discontinue answered 5/7, 2017 at 9:46 Comment(3)
OK, I know your problem is how to process ZonedDateTime. I just update the answer, maybe it can solve your problem.Discontinue
not working. ZonedDateTime zonedDateTime = mapper.readValue(date, ZonedDateTime.class); throwing errorVacation
What exception? and Which version of Jackson do you use? It should be greater than 2.8.5. According to my demo, it should work. I just update the answer with maven dependencyDiscontinue
P
1

If your input represents a ZonedDateTime and you want to convert it to a LocalDateTime, you can do the following.

I've created a sample class with a LocalDateTime field:

public class ZoneToLocalTest {

    @JsonDeserialize(using = CustomZonedToLocalDeserializer.class)
    private LocalDateTime date;

    // getter and setter
}

And also created the deserializer class:

public class CustomZonedToLocalDeserializer extends LocalDateTimeDeserializer {
    public CustomZonedToLocalDeserializer() {
        super(DateTimeFormatter.ISO_ZONED_DATE_TIME);
    }
}

I've tested with the input 2017-07-05T14:10:45.432+01:00[Europe/London] and the result was a LocalDateTime with the value 2017-07-05T14:10:45.432.

If the input is in a different format, then you need to use this format in the CustomZonedToLocalDeserializer class (instead of using DateTimeFormatter.ISO_ZONED_DATE_TIME, you'd use DateTimeFormatter.ofPattern(pattern)).

Plumbiferous answered 5/7, 2017 at 13:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.