如何在jackson mapper的帮助下使用单个JSON文件创建多种类型的java对象?

时间:2018-06-03 18:46:15

标签: java object hashmap jackson geojson

我想使用单个JSON文件创建多种类型的java对象

我想过以map的形式存储不同类型的java对象,其中key是对象类型的名称,value将是Object本身,如下所示

Field2_AllIn1.json

 {
 "fetchMapOfStringType": {

        "hi": "hello"

    },

    "fetchMapFieldType": {

        "5b0b8a5545424a20487ee2bc": {
            "fieldId": "5b0b8a5545424a20487ee2bc",

            "value": "25",
            "values": [],
            "visible": true,
            "fieldValidationErrors": [],
            "globalValidationErrors": [

                {
                    "fieldValidationId": "5b0b8a5545424a20487ee2bc",
                    "validationErrorMessage": "this is error"

                }
            ],
            "formulaErrors": []
        }

    }


 }

第一个存储一个简单的String类型 第二个存储类型为map的java对象,其中Field是自定义类

public class JsonJacksonAllInOne {

    public static void main(String args[]) throws JsonParseException, JsonMappingException, IOException{



        try {



            // read JSON from a file
            Map<String, Object> map = mapper.readValue(
                    new File("C://json/Field2_AllIn1.json"), 
                    new TypeReference<Map<String, Object>>() {
            });

            //type String
            //String type works fine
            Object obj1 = map.get("fetchMapOfStringType");
             Map<String, String> mapStringType  =  (Map<String, String>) obj1;
            System.out.println(mapStringType.get("hi"));//this prints hello


             //second type ... type casting to object type to objectId and Field map 
             Map<ObjectId, Field> map1 = (Map<ObjectId, Field>) map.get("fetchMapFieldType");

             ObjectId k1 = new ObjectId("5b0b8a5545424a20487ee2bc");
             Field f1 = map1.get(k1);
             //this code gives value of f1 as null


             // this gives class cast exception 
             // java.util.LinkedHashMap cannot be cast to com.dto.Field

                Field f2 =  map1.get("5b0b8a5545424a20487ee2bc");


        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }



    }
}

您可以在代码中看到注释。 一个给出null other给出了类强制转换异常 我想这个演员没有用 如何获取所需类型的对象 有没有其他方法我可以使用单个JSON文件来创建不同的Java对象,如地图和自定义类列表? ? 我想避免使用不同的JSON文件来创建不同的java对象

1 个答案:

答案 0 :(得分:1)

问题在于这一行:

// read JSON from a file
Map<String, Object> map = mapper.readValue(
                    new File("C://json/Field2_AllIn1.json"), 
                    new TypeReference<Map<String, Object>>() {
            });

当您将json作为Map读取时,它将整个json解析为LinkedHashMap(也用于存储顺序,否则也可以使用HashMap)。 之后你不能把它投射到另一个POJO / Beans。

解决方案是将json作为树读取,然后在需要时直接转换为您的POJO以避免不必要的类型转换,这里是更新的代码。

public static void main(String[] args) {

    try {

        ObjectMapper mapper = new ObjectMapper();

        // read JSON from a file as a tree
        JsonNode map = mapper.readTree(new File("/home/pratapi.patel/config.json"));

        // fetch json node from the tree
        JsonNode obj1 = map.get("fetchMapOfStringType");

        // convert obj1 (JsonNode) as Map<String, String>
        Map<String, String> mapStringType =
                mapper.readValue(mapper.treeAsTokens(obj1), new TypeReference<Map<String, String>>() {
                });

        // prints hello
        System.out.println(mapStringType.get("hi"));

        // fetch another json node from the tree
        JsonNode map1 =  map.get("fetchMapFieldType");

        // convert map1 (JsonNode) as Map<ObjectId, Field>
        Map<ObjectId, Field> mapFieldType = mapper.readValue(mapper.treeAsTokens(map1), new TypeReference<Map<ObjectId, Field>>() {
        });

        ObjectId k1 = new ObjectId("5b0b8a5545424a20487ee2bc");
        Field f1 = mapFieldType.get(k1);

        System.out.println(f1);

    } catch (IOException e) {
        e.printStackTrace();
    }
}

此外,由于ObjectId在Map中被用作键,因此它应该是final,并且应该重写equals / hashCode以正常工作。

public class ObjectId {

    private final String value;

    @JsonCreator
    public ObjectId(@JsonProperty("value") String value) {
        super();
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    /**
     * Auto generated in eclipse
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((value == null) ? 0 : value.hashCode());
        return result;
    }

    /**
     * Auto generated in eclipse
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ObjectId other = (ObjectId) obj;
        if (value == null) {
            if (other.value != null)
                return false;
        } else if (!value.equals(other.value))
            return false;
        return true;
    }
}