0

after adding a custom serializer for Instant toString is failing on JsonNode.

I have the below configuration for ObjectMapper.

 private static final ObjectMapper MAPPER = new ObjectMapper();
    static {
            
            MAPPER.registerModule(new SimpleModule());
            MAPPER.registerModule(new ParameterNamesModule());
            MAPPER.registerModule(new Jdk8Module());
            MAPPER.registerModule(new JavaTimeModule());
            SimpleModule module = new SimpleModule();
            module.addSerializer(Instant.class, new InstantSerializer());
            module.addDeserializer(Instant.class,new InstantDeSerializer());
            MAPPER.registerModule(module);
            MAPPER.setVisibility(MAPPER.getSerializationConfig().getDefaultVisibilityChecker()
                    .withFieldVisibility(ANY)
                    .withGetterVisibility(NONE)
                    .withSetterVisibility(NONE)
                    .withCreatorVisibility(ANY));
            MAPPER.disable(FAIL_ON_EMPTY_BEANS);
            MAPPER.disable(FAIL_ON_UNKNOWN_PROPERTIES);
            MAPPER.disable(WRITE_DATES_AS_TIMESTAMPS);
            MAPPER.setNodeFactory(JsonNodeFactory.withExactBigDecimals(true));
        }

Below are Serializer and De-serializer for Instant.

public class InstantSerializer extends StdSerializer<Instant> {

    public InstantSerializer() {
        this(null);
    }

    public InstantSerializer(Class<Instant> t) {
        super(t);
    }

    @Override
    public void serialize(
            Instant value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonProcessingException {
        jgen.writeEmbeddedObject(value);
    }
}

public class InstantDeSerializer extends StdDeserializer<Instant> {

    public InstantDeSerializer() {
        this(null);
    }

    protected InstantDeSerializer(final Class<?> vc) {
        super(vc);
    }

    @Override
    public Instant deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException, JacksonException {

        if (p.currentToken() == JsonToken.VALUE_EMBEDDED_OBJECT) {
            return (Instant) p.getEmbeddedObject();
        }
        else if (p.currentToken() == JsonToken.VALUE_NUMBER_INT) {
            return Instant.ofEpochMilli(p.getLongValue());
        }
        else if (p.currentToken() == JsonToken.VALUE_STRING) {
            return Instant.parse(p.getValueAsString());
        }

        throw new RuntimeException();
    }
}

I have below class

public  class A{
        private Instant time;

        public Instant getTime() {
            return time;
        }

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

below is the test

@Test
    public void test() {
        A a = new A();
        a.setTime(Instant.now());
        final JsonNode jsonNode = MAPPER.readTree(a);
        System.out.println(jsonNode);
    }

I get the below exception though JavaTimeModule is registered. could someone help me Thanks in advance

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
    at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276)
    at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35)
    at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:1118)
    at com.fasterxml.jackson.databind.node.POJONode.serialize(POJONode.java:115)
    at com.fasterxml.jackson.databind.node.ObjectNode.serialize(ObjectNode.java:328)
    at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:39)
    at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:20)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
    at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1514)
    at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1215)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1085)
    at com.fasterxml.jackson.databind.node.InternalNodeMapper.nodeToString(InternalNodeMapper.java:30)
    ... 92 more
Karunakar Reddy L
  • 342
  • 1
  • 4
  • 21
  • 1
    Have a look at https://github.com/FasterXML/jackson-modules-java8 – j_b Nov 15 '21 at 13:39
  • Does this answer your question? [Java 8 LocalDate Jackson format](https://stackoverflow.com/questions/28802544/java-8-localdate-jackson-format) – samabcde Nov 15 '21 at 13:43
  • 1
    You should use default (de)serializers for `Instant`, but if you want to write your own, you should pass `Instant.class` to `Std(De)Serializer`. Otherwise jackson will never call your custom serializer and deserializer – geobreze Nov 15 '21 at 13:48
  • 1
    Serialization and Deserialisation are working fine and the call is going through custom serializer and De-Serializer. only toString on JsonNode is not working. – Karunakar Reddy L Nov 15 '21 at 14:20
  • @samabcde that is not solving my problem – Karunakar Reddy L Nov 15 '21 at 14:21

0 Answers0