How arbitrary JSON string can be deserialized to j

2020-08-09 06:02发布

问题:

Lets say we have simple json string json = {"key1":"value1", "key2":"value2"} and java class

class Foo {
private String field1;
private Integer field2;
//setter & getter
}

Moreover we don't want to change the Foo class. Note that json keys don't match with Foo's fields name. Is there simple way we can deserilize json string to Foo class with Jackson or any other library?

回答1:

You can use the following json libraries and build a custom deserializer as shown below.

jackson-annotations-2.10.4,
jackson-core-2.10.4,
jackson.databind-2.10.4

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.IntNode;

import java.io.IOException;

public class FooDeserializer extends StdDeserializer<Foo> {


    public static void main (String [] args) throws JsonProcessingException {

        String json = "{\"key1\":\"value1\", \"key2\":100}";
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Foo.class, new FooDeserializer());
        mapper.registerModule(module);

        Foo foo = mapper.readValue(json, Foo.class);

        System.out.println(foo);
    }


    public FooDeserializer() {
        this(null);
    }

    public FooDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Foo deserialize(JsonParser jp, DeserializationContext ctx)
            throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        String field1 = node.get("key1").asText();
        int field2 = (Integer) ((IntNode) node.get("key2")).numberValue();

        return new Foo(field1,field2);
    }
}