2017-06-17 88 views
0

我想问你的帮助。我有一个设备对象追加生成的json树

public class Device { 
    public String name; 
    public String deviceId; 

    @JsonSerialize(using = CustomResourceSerializer.class) 
    public Map<String, Map<String, Object>> customResources; 
} 

我的目标是“提取”该地图直接到设备对象。首先我使用@JsonAnyGetter,它运行良好,并且Map直接嵌套在Device对象的第一个map字段String下。

但我需要更复杂的逻辑,我有两个问题,我不知道如何解决。

  1. 第一张地图的关键字是例如"configuration/inputOne"。随着@JsonAnyGetter的例子输出{ "configuration/inputOne": { "rate":23 } }

我需要的是基于分隔符嵌套结构,所以

{ "configuration": { "inputOne": { "rate":23 } } } 

这个我几乎能与定制容易做JsonSerializer

jsonGenerator.writeStartObject(); 
foreach(splited key) 
    jsonGenerator.writeObjectFieldStart(resourceUriItem); 
foreach(value) 
    jsonGenerator.writeObjectField(k, v); 
foreach(splitted key) 
    jsonGenerator.writeEndObject(); 
jsonGenerator.writeEndObject(); 

但最终物体看起来像

{ "customResource": {"configuration": { "inputOne": { "rate":23 } } } } 

CustomResource字段来自Device对象,我不知道如何摆脱它。与JsonAnyGetter一样。这是第一个问题。

  • 正如所看到的,我分裂映射的键为具有多个嵌套strucutre,所以从“配置/ inputOne”到{ configuration { inputOne { .. } }。但地图customResources可以有当然多个项目,因此,例如:

    • "configuration/inputOne"
    • "configuration/inputTwo"
    • "configuration"
  • 现在,你可能会看到哪里出了问题。当我遍历键和我创建嵌套结构时,我会覆盖它。例如,首先,我将创建对象配置,然后输入一个并填充字段。关闭对象。然后在地图中的第二项,创建配置对象和inputTwo对象。但是通过创建配置,我将删除以前使用inputOne创建的一个。

    你有什么建议如何解决这个问题吗?谢谢。

    回答

    0

    您可以通过拆分/并在拆分项目上创建父子关系来将地图转变为树的类型。

    将以下类用作树元素/节点。

    class TreeElement { 
        private String key; 
        private Object value; 
    
        private List<TreeElement> children; 
    
        public TreeElement(String key) { 
         this.key = key; 
        } 
    
        // getters and setters here 
    
        public void addChild(TreeElement child) { 
         if (this.children == null) { 
          this.children = new ArrayList<TreeElement>(); 
         } 
    
         this.children.add(child); 
        } 
    
        @Override 
        public int hashCode() { 
         final int prime = 31; 
         int result = 1; 
    
         result = prime * result + ((key == null) ? 0 : key.hashCode()); 
    
         return result; 
        } 
    
        @Override 
        public boolean equals(Object obj) { 
         if (this == obj) 
          return true; 
    
         if (obj == null) 
          return false; 
    
         if (getClass() != obj.getClass()) 
          return false; 
    
         TreeElement other = (TreeElement) obj; 
         if (key == null) { 
          if (other.key != null) 
           return false; 
    
         } else if (!key.equalsIgnoreCase(other.key)) 
          return false; 
    
         return true; 
        } 
    
        @Override 
        public String toString() { 
         return "TreeElement [key=" + key + ", value=" + value + ", children=" + children + "]"; 
        } 
    } 
    

    和下面的测试代码。

    public static void main(String[] args) { 
         try { 
          // create the config1, config2, etc.. here 
    
          Device device1 = new Device(); 
    
          device1.customResources = new HashMap<String, Map<String, Object>>(); 
          device1.customResources.put("configuration/inputOne", config1); 
          device1.customResources.put("configuration/inputTwo", config2); 
          device1.customResources.put("configuration", config3); 
          device1.customResources.put("configuration", duplicateConfig3); 
          device1.customResources.put("otherConfig", otherConfig); 
          device1.customResources.put("thirdConfig1", thirdConfig1); 
          device1.customResources.put("thirdConfig1/inputOne", thirdConfig2); 
          device1.customResources.put("thirdConfig1/inputOne", duplicateThirdConfig2); 
    
          List<TreeElement> elements = new ArrayList<TreeElement>(); 
    
          for (Map.Entry<String, Map<String, Object>> entry : device1.customResources.entrySet()) { 
           TreeElement element = generateElement(null, entry.getKey(), entry.getValue()); 
    
           elements.add(element); 
          } 
    
          List<TreeElement> joinedElements = joinElements(elements); 
    
          for (TreeElement e : joinedElements) { 
           System.out.println(e.getKey() + " - " + e.getValue()); 
    
           if (e.getChildren() != null) { 
            for (TreeElement c : e.getChildren()) { 
             System.out.println("\t" + c.getKey() + " - " + c.getValue()); 
            } 
           } 
          } 
         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
        } 
    

    该方法从Map>变量生成TreeElement。

    ​​

    此方法将常见TreeElement对象连接到一个父级和多个子级中。

    private static List<TreeElement> joinElements(List<TreeElement> elements) { 
         List<TreeElement> joinedElements = new ArrayList<TreeElement>(); 
    
         for (TreeElement element : elements) { 
          if (joinedElements.contains(element) == true) { 
           // joined elment does not have children 
           if (joinedElements.get(joinedElements.indexOf(element)).getChildren() == null) { 
            joinedElements.get(joinedElements.indexOf(element)).setChildren(element.getChildren()); 
           } else { 
            //joined element has children and the current element also has children 
            if (element.getChildren() != null) { 
             joinedElements.get(joinedElements.indexOf(element)).getChildren().addAll(element.getChildren()); 
            } 
           } 
    
           /* 
           * set the value of joined element to the value of the current element; will overwrite 
           * any existing value if duplicates exist 
           */ 
           if (element.getValue() != null) { 
            joinedElements.get(joinedElements.indexOf(element)).setValue(element.getValue()); 
           } 
          } else { 
           joinedElements.add(element); 
          } 
         } 
    
         return joinedElements; 
        } 
    

    我不知道这个代码是多么有效,但你得到下面的输出,你可以在你的定制序列遍历打印到JSON。

    thirdConfig1 - {rate=30} 
        inputOne - {rate=3020} 
    configuration - {rate=1200} 
        inputOne - {rate=23} 
        inputTwo - {rate=50} 
    otherConfig - {rate=10}