【问题标题】:Jackson: convert JSON representing a Map<String,Object> of single-field POJO's to a Map<String,String> of field values?杰克逊:将表示单字段 POJO 的 Map<String,Object> 的 JSON 转换为字段值的 Map<String,String>?
【发布时间】:2021-01-27 14:51:09
【问题描述】:

我有一个复杂的JSON 对象,类似于以下内容:

{
    unneededObject1: {...},
    unneededObject2: {...},
    ....,
    bigTargetObject: {
        "ABC": {
            targetField: "1234",
            unneededField1: "abcd",
            unneededField2: "abcd",
            ...
        },
        "DEF": {
            targetField: "2345",
            unneededField1: "abcd",
            unneededField2: "abcd",
            ...
        },
        ...
    }
}

根包含许多对象,我需要挑选一个,它是内部对象的列表(每个对象都由唯一的字符串标识)。我的目标输出是一个简单的Map&lt;String,String&gt;,如下所示:

{
"ABC": "1234",
"DEF": "2345",
...
}

我可以通过迭代对象和转换事物来想办法做到这一点,但我试图找到使用杰克逊注释对象的最干净的方法。我的目标是我可以这样使用:

JsonNode entireGiantObject = callService(...);
MyObjectType temp = mapper.convertValue(entireGiantObject, MyObjectType.class);
Map<String,String> targetMap = temp.getTargetMap();

到目前为止,我已经通过创建如下一对类来隔离“bigTargetObject”和内部“targetField”:

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyObjectType {

    private Map<String, TargetField> targetMap;

    @JsonProperty("bigTargetObject")
    private void renameMap(Map<String, TargetField> bigTargetObject) {
        this.targetMap = bigTargetObject;
    }

}

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class TargetField {

    private String targetField;

}

所以此时我的结果是Map&lt;String,TargetField&gt; 类型。更进一步并自动生成Map&lt;String,String&gt; 的最干净的方法是什么?请注意,“TargetField”类的存在仅用于过滤原始 JSON 中的字段名称,否则它只是单个字符串的包装器。

【问题讨论】:

    标签: java json jackson deserialization json-deserialization


    【解决方案1】:

    你可以使用com.fasterxml.jackson.annotation.JsonAnySetter注解。将课程MyObjectType 更改为:

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    class MyObjectType {
    
        private Map<String, TargetField> targetMap = new HashMap<>();
    
        @JsonAnySetter
        private void renameMap(String key, TargetField targetField) {
            targetMap.put(key, targetField);
        }
    }
    

    你将能够像这样阅读它:

    JsonNode bigO = entireGiantObject.get("bigTargetObject");
    MyObjectType myObjectType = mapper.convertValue(bigO, MyObjectType.class);
    System.out.println(myObjectType);
    

    您也可以使用JsonPath 库。

    【讨论】:

      猜你喜欢
      • 2020-05-20
      • 2013-05-24
      • 2014-01-29
      • 1970-01-01
      • 2015-11-21
      • 2013-07-15
      • 2013-05-01
      • 1970-01-01
      相关资源
      最近更新 更多