[FAQ] Tipo de data/hora Java 8 `java.time.LocalDateTime` não suportado por padrão: problema de serialização de data

Descrição do Problema

Ao serializar e desserializar uma coleção contendo objetos LocalDateTime, você poderá encontrar a seguinte exceção:

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"])

Isso ocorre porque a biblioteca Jackson não oferece suporte à serialização e desserialização do tipo LocalDateTime por padrão. Para resolver este problema, precisamos customizar o comportamento de serialização e desserialização.

Solução um

1. Introduzir dependências

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

2. Definir módulo de tempo

        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);

Solução 2

1. Serializador personalizado

Primeiro, precisamos criar um serializador personalizado para lidar com a serialização e desserialização do tipo LocalDateTime. A implementação específica é a seguinte:

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());
    }
}

Neste serializador personalizado, convertemos o objeto LocalDateTime em uma string e, em seguida, usamos gen.writeString()o método para gravá-lo no fluxo de saída JSON.

A seguir, precisamos aplicar este serializador personalizado à nossa classe de entidade. Suponha que temos uma Eventclasse de entidade chamada que contém uma propriedade do tipo 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;
    }
}

Adicionando uma anotação ao método e especificando o serializador customizado que acabamos de criar ( ), podemos garantir que getEventTime()o serializador customizado que definimos seja usado ao serializar e desserializar propriedades.@JsonSerializeUsing = LocalDateTimeSerializer.classeventTime

2. Desserializador personalizado (opcional)

Se desejarmos preservar as informações de tipo de um objeto LocalDateTime ao desserializar, podemos criar um desserializador personalizado. A implementação específica é a seguinte:

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
    }
}

Acho que você gosta

Origin blog.csdn.net/luansj/article/details/133383273
Recomendado
Clasificación