[FAQ] Le type de date/heure Java 8 `java.time.LocalDateTime` n'est pas pris en charge par défaut : problème de sérialisation de la date

Description du problème

Lors de la sérialisation et de la désérialisation d'une collection contenant des objets LocalDateTime, vous pouvez rencontrer l'exception suivante :

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Java 8 date/time type `java.time.LocalDate` not supported by default: add Module 
"com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: java.util.HashMap["data"])

En effet, la bibliothèque Jackson ne prend pas en charge la sérialisation et la désérialisation du type LocalDateTime par défaut. Pour résoudre ce problème, nous devons personnaliser le comportement de la sérialisation et de la désérialisation.

Première solution

1. Introduire des dépendances

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

2. Définir le module horaire

        ObjectMapper objectMapper = new CustomObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"));
        objectMapper.registerModule(new JavaTimeModule());
        Map<String, Object> map = new HashMap<>();
        map.put("time", LocalDateTime.now());
        map.put("data", LocalDate.now());
        objectMapper.writeValueAsString(map);

Solution 2

1. Sérialiseur personnalisé

Tout d’abord, nous devons créer un sérialiseur personnalisé pour gérer la sérialisation et la désérialisation du type LocalDateTime. La mise en œuvre spécifique est la suivante :

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.LocalDateTime;

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    
    
    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
    
    
        gen.writeString(value.toString());
    }
}

Dans ce sérialiseur personnalisé, nous convertissons l'objet LocalDateTime en chaîne, puis utilisons gen.writeString()la méthode pour l'écrire dans le flux de sortie JSON.

Ensuite, nous devons appliquer ce sérialiseur personnalisé à notre classe d'entité. Supposons que nous ayons une Eventclasse d'entité nommée qui contient une propriété de type LocalDateTime eventTime:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.time.LocalDateTime;

public class Event {
    
    
    private String name;
    private LocalDateTime eventTime;

    // getter and setter methods ...

    @JsonSerialize(using = LocalDateTimeSerializer.class)
    public LocalDateTime getEventTime() {
    
    
        return eventTime;
    }

    public void setEventTime(LocalDateTime eventTime) {
    
    
        this.eventTime = eventTime;
    }
}

En getEventTime()ajoutant @JsonSerializeune annotation sur la méthode et en spécifiant le sérialiseur personnalisé que nous venons de créer ( ), nous pouvons garantir que le sérialiseur personnalisé que nous avons défini est utilisé lors Using = LocalDateTimeSerializer.classde la sérialisation et de la désérialisation des propriétés.eventTime

2. Désérialiseur personnalisé (facultatif)

Si nous souhaitons conserver les informations de type d'un objet LocalDateTime lors de la désérialisation, nous pouvons créer un désérialiseur personnalisé. La mise en œuvre spécifique est la suivante :

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
    
    
    private static final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
    private static final LocalDateTime minValue = LocalDateTime.MIN;
    private static final LocalDateTime maxValue = LocalDateTime.MAX;
    private static final long serialVersionUID = 1L; // Add a unique ID to the deserializer if needed

    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
    
    
        String value = p.getText();
        return LocalDateTime.parse(value, formatter); // Use the same formatter as in the serializer for consistency
    }
}

Guess you like

Origin blog.csdn.net/luansj/article/details/133383273