我想用杰克逊迭代一个大的Json属性和子属性名称

时间:2017-09-28 07:32:48

标签: java json jackson

我的最终目标是从本地文件路径获取所有属性名称及其类型。

Example 
{
  "description": "Something",
  "id": "abc.def.xyzjson#",
  "type": "object",
  "properties": {
    "triggerTime": {
      "type": "string",
      "description": "Time of adjustment event",
      "source": "ab.cd",
      "pattern": "something",
      "required": true
    },
    "customerId": {
      "type": "string",
      "description": "Something",
      "source": "ef.gh",
      "required": true
    }, ..... many more properties 

在某些属性下,有子属性及其类型。 我想要最终输出 - triggerTime字符串 customerId String(也是sub)

2 个答案:

答案 0 :(得分:0)

我的建议是将json加载到Map<String, Object>然后以递归方式迭代地图并收集所需的数据

以下是适合您的整个解决方案

public class JsonProperties
{
    @SuppressWarnings("unchecked")
    public static void main(String[] args)
    {
        ObjectMapper mapper = new ObjectMapper();
        try (InputStream is = new FileInputStream("C://Temp/xx.json")) {
            Map<String, Object> map = mapper.readValue(is, Map.class);
            List<Property> properties = getProperties((Map<String, Object>)map.get("properties"));
            System.out.println(properties);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unchecked")
    public static List<Property> getProperties(Map<String, Object> propertiesMap) {

        List<Property> propertiesList = new ArrayList<>();

        // iterate on properties
        for (Map.Entry<String, Object> propertyEntry : propertiesMap.entrySet()) {
            Property property = new Property();
            property.name = propertyEntry.getKey();
            Map<String, Object> propertyAttrsMap = (Map<String, Object>)propertyEntry.getValue();
            property.type = (String)propertyAttrsMap.get("type");
            // recursively get sub properties 
            if (propertyAttrsMap.containsKey("properties")) {
                property.subProperties = getProperties((Map<String, Object>)propertyAttrsMap.get("properties"));
            }
            propertiesList.add(property);
        }

        return propertiesList;
    }

    public static class Property {
        public String name;
        public String type;
        public List<Property> subProperties = new ArrayList<>();

        @Override
        public String toString() {
            return name + " " + type + " " + subProperties;
        }
    }
}

使用此示例输入

{
  "description": "Something",
  "id": "abc.def.xyzjson#",
  "type": "object",
  "properties": {
    "triggerTime": {
      "type": "string",
      "description": "Time of adjustment event",
      "source": "ab.cd",
      "pattern": "something",
      "required": true
    },
    "customerId": {
      "type": "string",
      "description": "Something",
      "source": "ef.gh",
      "required": true
    },
    "complex": {
      "type": "string",
      "description": "Something",
      "source": "ef.gh",
      "required": true,
      "properties": {
        "sub1": {
          "type": "int",
          "description": "sub1",
          "source": "ab.cd",
          "required": true
        },
        "sub2": {
          "type": "short",
          "description": "sub2",
          "source": "ab.cd",
          "required": true
        }
      }
    }
  }
}

产生以下输出:

[triggerTime string [], customerId string [], complex string [sub1 int [], sub2 short []]]

答案 1 :(得分:0)

您的问题有多种解决方案。

只要迭代大地图,沙龙就会提出一个建议。

然而,另一个解决方案是创建要使用的包装类(POJO),这也可以根据您的规模和用例提供其他有用的方面。

public class YourJsonObject {

private String description;

private string id;

private String object;

private JsonProperties properties;

public YourJsonObject() {

}

public JsonProperties getProperties(){
return properties;
}

public void setProperties(JsonProperties properties){
this.properties = properties;
}

public String getDescription(){
return description;
}

public void setDescription(String description) {
this.description= description;
}

public String getId(){
return id;
}

public void setId(String id){
this.id = id;
}

//and so on with the getter setter
}


//The class JsonProperties used in YourJsonObject
public class JsonProperties{

private TriggerTime triggertime;

private Customer customerId;

public JsonProperties() {

}

public TriggerTime getTriggertime(){
return triggertime;
}

//and so on

}

然后在其他地方你可以这样做:

ObjectMapper mapper = new ObjectMapper(); // create once, reuse
yourJsonObject example = new yourJsonObject(); // have your POJO you want to save
mapper.writeValue(new File("result.json"), example);

要阅读,您可以使用:

ObjectMapper mapper = new ObjectMapper(); // create once, reuse
yourJsonObject value = mapper.readValue(new File("data.json"), yourJsonObject .class); // data.json is the json file you want to read. Else you can also pass a String into it with method overloading.

两个片段都来自杰克逊自己的链接维基文章。

如果配置正确,杰克逊应该能够自动将此POJO解析为等效的JSON。注意:杰克逊必须在全球注册,并且必须了解它。请阅读您使用的wiki知道它。 Jackson in 5 Minutes