Skip to content

Instantly share code, notes, and snippets.

@zhangguangyan
Last active March 29, 2019 22:50
Show Gist options
  • Save zhangguangyan/5c74e94b21384dd3506a96f7a19e16d7 to your computer and use it in GitHub Desktop.
Save zhangguangyan/5c74e94b21384dd3506a96f7a19e16d7 to your computer and use it in GitHub Desktop.
jackson deserialization without annotation (metadata)

jackson version: 2.9.8

package z.jack;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import java.io.IOException;

public class Animal {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static class Deserializer extends StdDeserializer<Animal> {
        private final ObjectMapper mapper;
        public Deserializer() {
            super(Animal.class);
            this.mapper = new ObjectMapper();
        }

        @Override
        public Animal deserialize(JsonParser p, DeserializationContext context) throws IOException {
            ObjectCodec codec = p.getCodec();
            TreeNode treeNode = codec.readTree(p);
            if (treeNode.get("lives") == null) {
                return mapper.treeToValue(treeNode, Animal.class);
            } else {
                return codec.treeToValue(treeNode, Cat.class);
            }
        }
    }
}

//-------
package z.jack;

public class Cat extends Animal {
    private int lives;

    public int getLives() {
        return lives;
    }

    public void setLives(int lives) {
        this.lives = lives;
    }
}
//----------------
package z.jack;

import java.util.List;

public class Zoo {
    private List<Animal> animals;

    public List<Animal> getAnimals() {
        return animals;
    }

    public void setAnimals(List<Animal> animals) {
        this.animals = animals;
    }
}

//---- test
package z.jack;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

public class JacksonPolyTest {
    private ObjectMapper mapper;

    @Before
    public void setUp() {
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Animal.class, new Animal.Deserializer());
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(module);
        this.mapper = mapper;

    }

    @Test
    public void testJsonToParent() throws IOException {
        List<Animal> animals = new ArrayList<>();
        Animal a1 = new Animal();
        a1.setName("what");
        animals.add(a1);
        Zoo zoo = new Zoo();
        zoo.setAnimals(animals);

        Writer w = new StringWriter();
        mapper.writeValue(w, zoo);
        String json = w.toString();
        System.out.println(json);

        Zoo deSerialized = mapper.readValue(json, Zoo.class);
        assert "what".equals(deSerialized.getAnimals().get(0).getName());
    }

    @Test
    public void testJsonToChild() throws IOException {
        List<Animal> animals = new ArrayList<>();
        Cat cat = new Cat();
        cat.setName("cat");
        cat.setLives(9);
        animals.add(cat);
        Zoo zoo = new Zoo();
        zoo.setAnimals(animals);

        String json = mapper.writeValueAsString(zoo);
        System.out.println(json);

        Zoo deSerialized = mapper.readValue(json, Zoo.class);
        assert "cat".equals(deSerialized.getAnimals().get(0).getName());
        assert 9 == (((Cat) deSerialized.getAnimals().get(0)).getLives());
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment