【问题标题】:Deserialize JSON Object with nested attributes使用嵌套属性反序列化 JSON 对象
【发布时间】:2020-09-23 06:13:38
【问题描述】:

我正在尝试反序列化具有属性的 json 对象

其中第一个键名未知,而内部映射始终包含名为“key1”和“key2”的两个属性。

{
   "operation_rand":
   {
      "key1": 1005, 
      "key2": 5
   }
}

我有代码:

Operation.java

public class Operation {
    private Map<String, Map<String, Integer>> operationDetails = new HashMap<>();
    
    @JsonAnyGetter
    public Map<String, Map<String, Integer>> getOperation() {
        return operationDetails;
    }
} 

主要

ObjectMapper mapper = new ObjectMapper();
   
Operation op = mapper.readValue(jsonData, Operation.class); 
Map<String, Map<String, Integer>> oDetails = address.getOperation();

但是我得到了错误: Can not deserialize instance of java.lang.String out of START_OBJECT token 第 1 行第 25 列,这是内部地图的起点。

关于如何映射内部地图的任何想法? 如果地图只有一层深,我可以获取正确的值。

{
   "operation_rand": 100
}

并将上面的地图调整为 Map&lt;String, Integer&gt;

【问题讨论】:

    标签: java json jackson annotations


    【解决方案1】:

    对于预期的 JSON 和 Gson 依赖项,您需要一个对象表示

    对象的类

    
        import com.fasterxml.jackson.annotation.JsonProperty;
        import com.fasterxml.jackson.annotation.JsonRootName;
    
        @JsonRootName("operation_rand")
        public class OperationRand{
        @JsonProperty("key1")
        private int key1;
        @JsonProperty("key2")
        private int key2;
    
        public int getKey1() {
            return key1;
        }
    
        public void setKey1(int key1) {
            this.key1 = key1;
        }
    
        public int getKey2() {
            return key2;
        }
    
        public void setKey2(int key2) {
            this.key2 = key2;
        }
    
        public OperationRand(int key1, int key2) {
            this.key1 = key1;
            this.key2 = key2;
        }
    
        @Override
        public String toString() {
            return "OperationRand{" +
                    "key1=" + key1 +
                    ", key2=" + key2 +
                    '}';
        }
        }
    
    

    来自 Google 的 Gson

        <dependency>
    
            <groupId>com.google.code.gson</groupId>
    
            <artifactId>gson</artifactId>
    
        </dependency>
    

    那么,

        String json ="{\n" +
                    "   \"operation_rand\":\n" +
                    "   {\n" +
                    "      \"key1\": 1005, \n" +
                    "      \"key2\": 5\n" +
                    "   }\n" +
                    "}";
        Gson gson = new Gson();
        OperationRand res = gson.fromJson(json, OperationRand.class);
    
        System.out.println(res);
        
    

    [编辑]用于更改操作_rand 我会将该对象用于不变的字段

    
        import lombok.*;
        
        @Setter
        @Getter
        @AllArgsConstructor
        @NoArgsConstructor
        @ToString
        public class Key {
        int key1;
        int key2;
        }
    
    

    主要

    
        Gson gson = new Gson();
        Map<String,Key> rest = gson.fromJson(json,HashMap.class);
        System.out.println(rest);
    
    

    【讨论】:

    • 有道理,但是我最初有@JsonAnyGetter,因为我不知道operation_rand 字符串的值。上面的代码不是假设值总是operation_rand吗?
    • 是的,但是我想我已经理解了这个要求。我将为不变的字段创建一个类,请在我放置示例代码的位置检查此代码共享。 codeshare.io/arDJQE
    【解决方案2】:

    100 不是 Map

    也许使用Map&lt;String,Object&gt; 而不是Map&lt;String, Map&lt;String, Integer&gt;&gt;

    instanceof Integerinstanceof Map判断类型。

    【讨论】:

      【解决方案3】:

      你只需要像这样简化类:

      public class Operation {
          @JsonProperty("operation_rand")
          private Map operationDetails;
          
          public Map getOperation() {
              return operationDetails;
          }
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-08
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        • 1970-01-01
        相关资源
        最近更新 更多