382 Stimmen

serialize/deserialize Java 8 Java.time mit Jackson JSON mapper

Wie verwende ich den Jackson JSON-Mapper mit Java 8 LocalDateTime?

org.codehaus.jackson.map.JsonMappingException: Kann den Wert des Typs [einfachen Typs, Klasse java.time.LocalDateTime] nicht aus JSON-String instanziieren; kein einzelner String-Konstruktor/Fabrikmethode vorhanden (durch Verweisreihe: MyDTO["field1"]->SubDTO["date"])

25voto

Witold Kaczurba Punkte 8919

Ich hatte ein ähnliches Problem beim Verwenden von Spring Boot. Mit Spring Boot 1.5.1.RELEASE musste ich lediglich die Abhängigkeit hinzufügen:

    com.fasterxml.jackson.datatype
    jackson-datatype-jsr310

18voto

walker088 Punkte 181

In der neueren Version von Jackson JSR ist beispielsweise die registerModule(new JSR310Module()) veraltet, jetzt wird stattdessen JavaTimeModule empfohlen

import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonFactory {
    private static ObjectMapper objectMapper = null;
    public static ObjectMapper getObjectMapper() {
        if (objectMapper == null) {
            objectMapper = new ObjectMapper();
            objectMapper.registerModule(new JavaTimeModule());
        }
        return objectMapper;
    }
}

13voto

Udo Punkte 2200

Wenn aus irgendeinem Grund jackson-modules-java8 nicht verwendet werden kann, können Sie das Instant-Feld als long (de-)serialisieren, indem Sie @JsonIgnore und @JsonGetter & @JsonSetter verwenden:

public class MyBean {

    private Instant time = Instant.now();

    @JsonIgnore
    public Instant getTime() {
        return this.time;
    }

    public void setTime(Instant time) {
        this.time = time;
    }

    @JsonGetter
    private long getEpochTime() {
        return this.time.toEpochMilli();
    }

    @JsonSetter
    private void setEpochTime(long time) {
        this.time = Instant.ofEpochMilli(time);
    }
}

Beispiel:

@Test
public void testJsonTime() throws Exception {
    String json = new ObjectMapper().writeValueAsString(new MyBean());
    System.out.println(json);
    MyBean myBean = new ObjectMapper().readValue(json, MyBean.class);
    System.out.println(myBean.getTime());
}

ergibt

{"epochTime":1506432517242}
2017-09-26T13:28:37.242Z

11voto

Sul Aga Punkte 5872

Wenn Sie Jersey verwenden, müssen Sie die Maven-Abhängigkeit (jackson-datatype-jsr310) hinzufügen, wie von anderen vorgeschlagen, und Ihre ObjectMapper-Instanz wie folgt registrieren:

@Provider
public class JacksonObjectMapper implements ContextResolver {

  final ObjectMapper defaultObjectMapper;

  public JacksonObjectMapper() {
    defaultObjectMapper = createDefaultMapper();
  }

  @Override
  public ObjectMapper getContext(Class type) {
    return defaultObjectMapper;
  }

  private static ObjectMapper createDefaultMapper() {
    final ObjectMapper mapper = new ObjectMapper();    
    mapper.registerModule(new JavaTimeModule());
    return mapper;
  }
}

Beim Registrieren von Jackson in Ihren Ressourcen müssen Sie diesen Mapper wie folgt hinzufügen:

final ResourceConfig rc = new ResourceConfig().packages("");
rc
  .register(JacksonObjectMapper.class)
  .register(JacksonJaxbJsonProvider.class);

7voto

edubriguenti Punkte 3926

Wenn Sie den Jackson Serializer verwenden, hier ist eine Möglichkeit, die Datumsmodule zu verwenden:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import org.apache.kafka.common.serialization.Serializer;

public class JacksonSerializer implements Serializer {

    private final ObjectMapper mapper = new ObjectMapper()
            .registerModule(new ParameterNamesModule())
            .registerModule(new Jdk8Module())
            .registerModule(new JavaTimeModule());

    @Override
    public byte[] serialize(String s, T object) {
        try {
            return mapper.writeValueAsBytes(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X