使用 Jackson ObjectMapper 将 Json 的一部分转换为 HashMap

Posted

技术标签:

【中文标题】使用 Jackson ObjectMapper 将 Json 的一部分转换为 HashMap【英文标题】:Convert a part of Json to HashMap using Jackson ObjectMapper 【发布时间】:2015-07-18 01:09:32 【问题描述】:

我正在尝试以一种方式解组 json 文件,以便将 Json 的少数属性映射到我的模型类中存在的 HashMap。其余属性映射到类的相应字段。请找到json如下:


         "_id":2,
         "Name":"xyz",
         "Age":20,
         "MEMO_TEXT":"yyy",
         "MEMO_LINK":"zzz",
         "MEMO_DOB":"",
         "MEMO_USERNAME":"linie orange",
         "MEMO_CATEGORY":2,
         "MEMO_UID":"B82071415B07495F9DD02C152E4805EC"
      

这是我想将此 Json 映射到的 Model 类:

public class Model

    private int                              _id;
    private String                           name;
    private int                              age
    private HashMap<String, String> columns;

    //Getters and Setter methods

所以在这里,我想要的是获得一个包含键 "MEMO_TEXT","MEMO_LINK","MEMO_DOB","MEMO_USERNAME","MEMO_CATEGORY","MEMO_UID" 的地图 columns

Json 中的其余属性映射到各自的字段。

是否可以使用 Jackson Library 的 ObjectMapper 来做到这一点?

【问题讨论】:

你可以自己写反序列化器 【参考方案1】:

您可以使用@JsonAnySetter 来注释要为“其他”属性调用的方法:

@Test
public void partial_binding() throws Exception 
    Model model = mapper.readValue(Resources.getResource("partial_binding.json"), Model.class);
    assertThat(model.name, equalTo("xyz"));
    assertThat(model.columns, hasEntry("MEMO_TEXT", "yyy"));
    assertThat(
            mapper.writeValueAsString(model),
            json(jsonObject()
                 .withProperty("Name", "xyz")
                 .withProperty("MEMO_TEXT", "yyy")
                 .withAnyOtherProperties()));


public static class Model 
    @JsonProperty
    private int _id;
    @JsonProperty("Name")
    private String name;
    @JsonProperty("Age")
    private int age;
    private HashMap<String, String> columns;

    @JsonAnyGetter
    public HashMap<String, String> getColumns() 
        return columns;
    

    public void setColumns(HashMap<String, String> columns) 
        this.columns = columns;
    

    @JsonAnySetter
    public void putColumn(String key, String value) 
        if (columns == null) columns = new HashMap<>();
        columns.put(key, value);
    

另外,@JsonAnyGetter 确实“有点相反”,所以这应该以相同的方式进行序列化和反序列化。

【讨论】:

@Puneetr90 很高兴为您提供帮助。如果您觉得您的问题已得到解答,请点击答案旁边的“打勾”标记,将其标记为“已接受”。【参考方案2】:

实现所需的几种方法之一是添加构造函数:

@JsonCreator
public Model(Map<String, Object> fields) 
    this._id = (int) fields.remove("_id");
    this.name = (String) fields.remove("Name");
    this.age = (int) fields.remove("Age");
    this.columns = new HashMap<String, String>();
    for (Entry<String, Object> column : fields.entrySet()) 
        columns.put(column.getKey(), column.getValue().toString());
    

请注意,如果将其序列化回 JSON,则结构将与初始结构不同。

【讨论】:

【参考方案3】:

尝试使用 SerializerProvider。 SerializerProvider 可以修改反序列化,启用自定义反序列化。

【讨论】:

以上是关于使用 Jackson ObjectMapper 将 Json 的一部分转换为 HashMap的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Jackson ObjectMapper 将 Json 序列化为 Java 对象

ObjectMapper类

使用 Jackson ObjectMapper 将 Json 的一部分转换为 HashMap

jackson.databind.ObjectMapper upperCasing json 数组和对象名称

Spring Boot 自定义Jackson ObjectMapper

Retrofit 或 Jackson ObjectMapper 将“aId”属性映射为小写“aid”