【问题标题】:Java classes to generate the given JSON string用于生成给定 JSON 字符串的 Java 类
【发布时间】:2018-05-05 15:23:20
【问题描述】:

我很难想出一个代表以下 JSON 的类。 “familyRelationships”是一个数组数组。每个数组都有 person1 和 person2 标识符以及 person1 和 person2 之间的关系。您可能已经猜到了,数组中值的顺序非常重要。例如,如果“12345”和“31142”位置互换,则表示“31142”是“12345”的PARENT,这是完全错误的。

{
    "familyRelationships": [
        [
            "12345", 
            "SPOUSE", 
            "67890", 
            {
                "careTaker": false,
                "liveTogether": true
            }
        ],
        [
            "12345", 
            "PARENT", 
            "31142", 
            {
                "careTaker": true,
                "liveTogether": true
            }
        ],
        [
            "67890", 
            "PARENT", 
            "31142", 
            {
                "careTaker": true,
                "liveTogether": true
            }
        ]
    ]
}

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    这应该可以使用自定义反序列化器来实现。

    在我看来,关系应该建模为具有正确名称的正确 java 类。请注意,构造函数将JSONNode 作为参数,并且我已经留下了我们的所有getter 和setter:

    public class Relationship {
    
        private final String id1;
        private final String id2;
        private final Relation relation;
        private final boolean careTaker;
        private final boolean liveTogether;
    
        public Relationship(JsonNode base) {
            this.id1 = base.get(0).asText();
            this.id2 = base.get(2).asText();
            this.relation = Relation.valueOf(base.get(1).asText());
            this.careTaker = base.get(3).get("careTaker").asBoolean();
            this.liveTogether = base.get(3).get("liveTogether").asBoolean();
        }
    
        public enum Relation {
            PARENT,
            SPOUSE;
        }
    
    }
    

    我们还需要一个存储集合的类。这是您将顶级对象反序列化为的对象(再次省略 getter 和 setter):

    @JsonDeserialize( using = FamillyRelationshipsDeserializer.class )
    public class FamillyRelationships {
    
        public List<Relationship> familyRelationships = new ArrayList<>();
    
    } 
    

    最后我们需要实现上面类中引用的实际JsonDeserializer。它应该如下所示。我用this question作为参考:

    class FamillyRelationshipsDeserializer extends JsonDeserializer<FamillyRelationships> {
        @Override
        public FamillyRelationships deserialize(JsonParser jp, DeserializationContext ctxt) throws 
                IOException, JsonProcessingException {
            FamillyRelationships relationships = new FamillyRelationships();
            JsonNode node = jp.readValueAsTree();
            JsonNode rels = node.get("familyRelationships");
    
            for (int i = 0; i < rels.size(); i++) {
                relationships.familyRelationships.add(new Relationship(rels.get(i));
            }
    
            return relationships;
        }
    }
    

    我希望这会有所帮助,我还没有实际测试过这些,它可能甚至无法编译,但原则应该是正确的。我还假设 JSON 是您提供的格式。如果这不是保证,那么您将需要进行适当的检查并处理任何偏差。

    如果您还希望能够序列化所有内容,则需要实现JsonSerializer,请参阅this question 了解更多详细信息。

    【讨论】:

      【解决方案2】:

      JSON 不会很好地成为 POJO,因为数组中包含的类型不一致:

      例如

      [
        "12345", 
        "SPOUSE", 
        "67890", 
        {
          "careTaker": false,
          "liveTogether": true
        }
      ]
      

      String,String,String,Object。唯一可行的方法是如果您有Object[]List&lt;Object&gt;。所以familyRelationships 实际上应该是List&lt;List&lt;Object&gt;&gt;。最终结果将需要大量转换(可能还需要进行一些检查以确保给定索引处的项目是您期望的类),但它会起作用。

      【讨论】:

      • 看起来这是唯一可用的选项。我希望有其他方法可以做到这一点。无论如何,谢谢。
      • 并非没有其他类型的间接。您可以做的是创建您自己的列表包装器来为您处理转换。它在组件中仍然是丑陋的,但它会保护你的应用程序的其余部分免受丑陋的影响。
      【解决方案3】:

      网上有一些工具可以帮你做到这一点

      package com.example;
      
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
      import com.fasterxml.jackson.annotation.JsonAnyGetter;
      import com.fasterxml.jackson.annotation.JsonAnySetter;
      import com.fasterxml.jackson.annotation.JsonIgnore;
      import com.fasterxml.jackson.annotation.JsonInclude;
      import com.fasterxml.jackson.annotation.JsonProperty;
      import com.fasterxml.jackson.annotation.JsonPropertyOrder;
      
      @JsonInclude(JsonInclude.Include.NON_NULL)
      @JsonPropertyOrder({
      "familyRelationships"
      })
      public class Example {
      
      @JsonProperty("familyRelationships")
      private List<List<String>> familyRelationships = null;
      @JsonIgnore
      private Map<String, Object> additionalProperties = new HashMap<String, Object>();
      
      @JsonProperty("familyRelationships")
      public List<List<String>> getFamilyRelationships() {
      return familyRelationships;
      }
      
      @JsonProperty("familyRelationships")
      public void setFamilyRelationships(List<List<String>> familyRelationships) {
      this.familyRelationships = familyRelationships;
      }
      
      @JsonAnyGetter
      public Map<String, Object> getAdditionalProperties() {
      return this.additionalProperties;
      }
      
      @JsonAnySetter
      public void setAdditionalProperty(String name, Object value) {
      this.additionalProperties.put(name, value);
      }
      
      }
      

      这只是使用http://www.jsonschema2pojo.org/ 制作的一种可能性

      【讨论】:

      • 我知道那个工具。生成的类没有帮助。 “familyRelationships”不是字符串数组。注意具有两个属性“careTaker”和“liveTogether”的对象。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-02
      • 2016-10-30
      • 2020-05-16
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 2011-05-13
      相关资源
      最近更新 更多