Jackson HashMap,写入字符串时忽略映射名称

Cos*_*inO 2 java pojo jackson jackson-databind

考虑如下 JSON:

{"randomName1": {
    "knownfield1": "a",
    "knownfield2": [1,3,2,4]
},
"randomName2": {
    "knownfield1": "0.20",
    "knownfield2": [1,2,3,4]
}
Run Code Online (Sandbox Code Playgroud)

}

public class PojoForJson {

HashMap<String, PojoType1> map = new HashMap<>();

@JsonAnyGetter
public HashMap<String , PojoType1> pojoType1Getter(){
    return map;
}

@JsonAnySetter
public void pojoType1Setter(String key, PojoType1 value){
    map.put(key,value);
}
Run Code Online (Sandbox Code Playgroud)

}

如果我有

PojoForJson pojo = new ObjectMapper().readValue(jsonInput,PojoForJson.class);
Run Code Online (Sandbox Code Playgroud)

然后我尝试将其写回 Json,我必须调用并且它工作正常。

new ObjectMapper().writeValueAsString(pojo.getMap());
Run Code Online (Sandbox Code Playgroud)

现在,这是另一个 POJO 中的字段,我们将其称为 PojoMain:

@Builder     
public class PojoMain {
@Getter @Setter
private Type1 t1;
@Getter @Setter
private Type2 t2;
@Getter @Setter @JsonUnwrapped
private PojoForMap pojoForMap;
}
Run Code Online (Sandbox Code Playgroud)

预期结果是一个 JSON 看起来像

    { 
      "t1":{...},
      "t2":{...},
      "randomName1":{...},
      "randomName2":{...},
      ...............
    }
Run Code Online (Sandbox Code Playgroud)

相反,它是

{ 
          "t1":{...},
          "t2":{...},
          "pojoForMap":{
             "map":{
                "randomName1":{...},
                 ...
             }
           }
        }
Run Code Online (Sandbox Code Playgroud)

如果我将 pojoForMap 更改为HashMap<String, PojoType1>

@Builder     
    public class PojoMain {
    @Getter @Setter
    private Type1 t1;
    @Getter @Setter
    private Type2 t2;
    @Getter @Setter @JsonUnwrapped
    private HashMap<String, PojoType1> pojoForMap;
    }
Run Code Online (Sandbox Code Playgroud)

我仍然得到:

{ 
              "t1":{...},
              "t2":{...},
              "pojoForMap":{
                   "randomName1":{...},
                    ........
                }
               }
            }
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何在主 POJO 中序列化映射条目本身,而不需要任何字段名称?我过去曾使用 List 来放弃这种麻烦并忽略实际的列表名称,但这是一种不同的情况,其中字段名称未知。

我尝试过使用List<Map.Entry<String, PojoType1>>List<Pair<String, PojoType1>>

@JsonUnwrapped 似乎不适用于 HashMaps

so-*_*ude 5

为什么我无法使用 Jackson Java 库解包和序列化 Java 映射?

在此引用相关答案

@JsonUnwrapped不适用于映射,仅适用于具有 getter 和 setter 的正确 POJO。对于地图,您应该使用@JsonAnyGetter@JsonAnySetter(在 jackson 版本 >= 1.6 中可用)。

对于您的情况,请尝试以下操作:

@JsonAnySetter 
public void add(String key, String value) {
    map.put(key, value);
}

@JsonAnyGetter
public Map<String,String> getMap() {
    return map;
}
Run Code Online (Sandbox Code Playgroud)

这样,您还可以直接向映射添加属性,例如向映射add('abc','xyz')添加一个带有 value 的新键。abcxyz

Jackson 项目目前有一个未解决的问题@JsonUnwrapped,允许在地图上提供支持。它没有被标记为出现在即将推出的 Jackson 2.10 或 3.x 版本中,因此它看起来并不在近期功能路线图上。

在支持此功能之前,使用@JsonAnySetter/的解决方法@JsonAnyGetter似乎是可行的方法。