Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do custom serialization/deserialization using JACKSON?

Tags:

java

gson

jackson

I am trying to convert the following gson serialization to JACKSON serialization. Please let me know what i need to change to make it work for JACKSON

public class AbstractElementAdapter 
    implements JsonSerializer<AbstractElement>, JsonDeserializer<AbstractElement>
{
    @Override
    public JsonElement serialize(AbstractElement src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject result = new JsonObject();
        JsonObject properties = context.serialize(src, src.getClass()).getAsJsonObject();

        if (src instanceof TruncatedElement) {
            result.add("type", new JsonPrimitive(((TruncatedElement) src).getClassName()));
            properties.remove("className");
        } else {
            result.add("type", new JsonPrimitive(src.getClass().getSimpleName()));
        }

        result.add("properties", properties);

        return result;
    }

    @Override
    public AbstractElement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObject = json.getAsJsonObject();
        String type = jsonObject.get("type").getAsString();
        JsonElement element = jsonObject.get("properties");

        try {
            return context.deserialize(element, Class.forName("com.zreflect.emyed.whiteboard.model.element." + type));
        } catch (ClassNotFoundException cnfe) {
            throw new JsonParseException("Unknown element type: " + type, cnfe);
        }
    }
}
like image 625
user1595858 Avatar asked Oct 18 '12 01:10

user1595858


People also ask

How do I add custom deserializer to Jackson?

To create a custom deserializer, we need to create a class extending StdDeserializer and then override its deserialize() method. We can use custom deserializer either by registering with ObjectMapper or annotating class with @JsonDeserialize . Now find the JSON used in our demo.

Does Jackson use serializable?

Introduction of ObjectMapper Class jackson. databind package and can serialize and deserialize two types of objects: Plain Old Java Objects (POJOs)


1 Answers

You can create a custom serializer, something like this:

  public class ItemSerializer extends JsonSerializer<AbstractElement> {
        @Override
        public void serialize(AbstractElement src, JsonGenerator jgen, SerializerProvider provider)
                throws IOException, JsonProcessingException {
            jgen.writeStartObject();

            if (src instanceof TruncatedElement) {
                jgen.writeStringField("type",((TruncatedElement) src).getClassName());
                jgen.writeObjectFieldStart("properties");
                //use  jgen.writeStringField();  
                //jgen.writeNumberField(); 
                //etc to every one of the values, 
                //but skipping className
                 jgen.writeEndObject();


            } else {
                jgen.writeStringField("type", src.getClass().getSimpleName() );
                //write everythin
                jgen.writeObjectField("properties", src);
            }

            jgen.writeEndObject();
        }
    }

And register it with the ObjectMapper and then do the serialization:

ObjectMapper mapper = new ObjectMapper();

SimpleModule module = new SimpleModule();
module.addSerializer(yourObject.class, new ItemSerializer());
mapper.registerModule(module);

String serialized = mapper.writeValueAsString(yourObject);

To the trick of skipping className, you could also want to use a custom field filter, you have a great example here: http://www.baeldung.com/jackson-ignore-properties-on-serialization

like image 181
Carlos Robles Avatar answered Sep 24 '22 10:09

Carlos Robles