Search code examples
javajsonserializationjson-deserializationjackson-databind

Serialize, deserialize using jackson


I was trying convert to my object to and from json but the default serializer, deserializer by jackson doesn't work.

How can I make this work? I understand I might need to write a custom serializer, deserializer. How can I do that? Is ther some annotation by adding which the code would work?

Here is the object:

@JsonDeserialize(keyUsing = mypairDeserializer.class)
@JsonSerialize(keyUsing = mypairSerializer.class)
HashMap<Set < Mypair > , List < Mypair > > obj;


public class ConditionSerializer extends JsonSerializer<Collection<mypair>> {

    @Override
    public void serialize(final Collection<mypair> conditionSet, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeFieldName("Pair");
        jsonGenerator.writeStartArray();
        for(final Condition condition: conditionSet) {
            jsonGenerator.writeString(mypair.toString());
        }
        jsonGenerator.writeEndArray();
        jsonGenerator.writeEndObject();
    }
}


public class mypairDeserializer extends KeyDeserializer {
    ObjectMapper mapper = new ObjectMapper();
    @Override
    public Collection<mypair> deserializeKey(final String key, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
        // return new mypair(key);
        return mapper.readValue(key, Collection.class);
    }
}

Solution

  • Hi again from last post,

    So, this is an example of what you can do :

    Note that since I don't know what is your object Mypair, I did this example with a User class :

    public class User {
        private int id;
        private String name;
    
        public User(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
    
        // getters & setters
    }
    

    The class containing your complex object :

    public class YourClass {
    
        @JsonSerialize(using = ComplexObjectSerializer.class)
        private Map<Set<User>, List<User>> object;
    
        public YourClass(Map<Set<User>, List<User>> object) {
            this.object = object;
        }
    
        public Map<Set<User>, List<User>> getObject() {
            return object;
        }
    
        public void setObject(Map<Set<User>, List<User>> object) {
            this.object = object;
        }
    }
    

    The custom serializer :

    public class ComplexObjectSerializer extends StdSerializer<Map<Set<User>, List<User>>> {
    
        public ComplexObjectSerializer() {
            this(null);
        }
    
        public ComplexObjectSerializer(Class<Map<Set<User>, List<User>>> t) {
            super(t);
        }
    
        private static final long serialVersionUID = 1L;
    
        @Override
        public void serialize(Map<Set<User>, List<User>> complexObject,
                JsonGenerator jsonGen, SerializerProvider arg2) throws IOException {
    
            // Suppose you want the following json:
            /**
             * [ { "set":[], "list":[] } ]
             */
    
            jsonGen.writeStartArray(); // [
    
            for (Entry<Set<User>, List<User>> entry : complexObject.entrySet()) {
                jsonGen.writeStartObject(); // {
                jsonGen.writeObjectField("set", entry.getKey()); // It will call the default serializer for a Set<User>, ie : [ {"id": 0, "name":"string"} ]
    
                jsonGen.writeObjectField("list", entry.getValue()); // It will call the default serializer for a List<User>, ie the same thing as the Set above
                jsonGen.writeEndObject(); // }
            }
            jsonGen.writeEndArray(); // ]
        }
    }
    

    Main :

            Map<Set<User>, List<User>> complexObject = new HashMap<Set<User>, List<User>>();
    
            // Add some data in the map ...
    
            YourClass yourClass = new YourClass(complexObject);
    
            // Serialize your object
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writeValueAsString(yourClass); // It will call your custom serializer
            System.out.println(json);
    

    Output :

    {
      "object": [
        {
          "set": [
            {
              "id": 5,
              "name": "userName5"
            },
            {
              "id": 6,
              "name": "userName6"
            }
          ],
          "list": [
            {
              "id": 2,
              "name": "userName2"
            }
          ]
        },
        {
          "set": [
            {
              "id": 4,
              "name": "userName4"
            },
            {
              "id": 3,
              "name": "userName3"
            }
          ],
          "list": [
            {
              "id": 0,
              "name": "userName0"
            },
            {
              "id": 1,
              "name": "userName1"
            }
          ]
        }
      ]
    }