Skip to content

Instantly share code, notes, and snippets.

@jeremychone
Last active May 5, 2021 13:21
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeremychone/a7e06b8baffef88a8816 to your computer and use it in GitHub Desktop.
Save jeremychone/a7e06b8baffef88a8816 to your computer and use it in GitHub Desktop.
A simple Java 8 centric Jackson Module wrapper for making custom serializer lambda friendly. (can be extended to support other Jackson Module custom methods)
package com.britecrm.util;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.time.ZonedDateTime;
import java.util.function.Function;
public class Jackson8Module extends SimpleModule{
public <T> void addStringSerializer(Class<T> cls, Function<T,String> serializeFunction){
JsonSerializer<T> jsonSerializer = new JsonSerializer<T>(){
@Override
public void serialize(T t, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
String val = serializeFunction.apply(t);
jgen.writeString(val);
}
};
addSerializer(cls,jsonSerializer);
}
public <T> void addStringDeserializer(Class<T> cls, Function<String, T> deserializeFunction) {
JsonDeserializer<T> jsonDeserializer = new JsonDeserializer<T>() {
@Override
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
String txt = jsonParser.getText();
return deserializeFunction.apply(txt);
}
};
addDeserializer(cls, jsonDeserializer);
}
}
// Here is how to create a new Jackson ObjectMapper with the Jackson8Module and add some custom serializer/deserializer
ObjectMapper jacksonMapper = new ObjectMapper();
Jackson8Module module = new Jackson8Module();
module.addStringSerializer(LocalDate.class, (val) -> val.toString());
module.addStringDeserializer(LocalDate.class, (txt) -> LocalDate.parse(txt));
module.addStringSerializer(LocalDateTime.class, (val) -> val.toString());
module.addStringDeserializer(LocalDateTime.class, (txt) -> LocalDateTime.parse(txt));
module.addStringSerializer(ZonedDateTime.class, (val) -> val.toString());
module.addStringDeserializer(ZonedDateTime.class, (txt) -> ZonedDateTime.parse(txt));
jacksonMapper.registerModule(module);
jacksonMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
jacksonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
@johannesjasper
Copy link

johannesjasper commented Dec 6, 2017

I modified the module, such that you can access the JsonParser and JsonGenerator

public class Jackson8Module extends SimpleModule {

    @FunctionalInterface
    public interface SerializerFunction<T, G> {
        void apply(T t, G g) throws IOException, JsonProcessingException;
    }

    @FunctionalInterface
    public interface DeserializerFunction<P, R> {
        R apply(P p) throws IOException, JsonProcessingException;
    }

    public <T> void addSerializer(Class<T> cls, SerializerFunction<T, JsonGenerator> serializeFunction) {
        JsonSerializer<T> jsonSerializer = new JsonSerializer<T>() {
            @Override
            public void serialize(T t,
                                  JsonGenerator jgen,
                                  SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
                serializeFunction.apply(t, jgen);
            }
        };
        addSerializer(cls, jsonSerializer);
    }

    public <T> void addDeserializer(Class<T> cls, DeserializerFunction<JsonParser, T> deserializeFunction) {

        JsonDeserializer<T> jsonDeserializer = new JsonDeserializer<T>() {
            @Override
            public T deserialize(JsonParser jsonParser,
                                 DeserializationContext deserializationContext) throws IOException {
                return deserializeFunction.apply(jsonParser);
            }
        };

        addDeserializer(cls, jsonDeserializer);
    }
}
    @Bean
    public Module customModule() {
        Jackson8Module module = new Jackson8Module();

        module.addSerializer(MyClass.class,
                             (val, jgen) -> {
                                 jgen.writeStartObject();
                                 jgen.writeStringField("...", ...);
                                 jgen.writeEndObject();
                             }
        );

        module.addDeserializer(MyClass.class,
                               (jsonParser) -> {
                                   JsonNode node = jsonParser.getCodec().readTree(jsonParser);
                                   String myField = node.get("myField").asText();
                                   return new MyClass(myField);
                               }
        );

        return module;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment