简体   繁体   English

使用 Jackson 反序列化成 Map

[英]Using Jackson to deserialize into a Map

I have a JSON object with two attributes: "key" which is a string, and "value" which can be deserialized into a Java bean.我有一个 JSON object 有两个属性:“key”是一个字符串,“value”可以反序列化为一个 Java bean。

{ "key": "foo", "value": "bar" }

The question is, given a list of such objects, can I deserialize it into a Map?问题是,给定这些对象的列表,我可以将其反序列化为 Map 吗?

[{"key": "foo1", "value": "bar1"}, {"key": "foo2", "value": "bar2"}] -> Map<String, String>

Currently using Jackson-databind 2.1目前使用 Jackson-databind 2.1

You can easily convert above JSON to List<Map<String, String>> : 您可以轻松地将上述JSON转换为List<Map<String, String>>

import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;

public class JacksonProgram {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        CollectionType mapCollectionType = mapper.getTypeFactory().constructCollectionType(List.class, Map.class);
        List<Map<String, String>> result = mapper.readValue(json, mapCollectionType);
        System.out.println(result);
    }
}

Above program prints: 上面的程序打印:

[{key=foo1, value=bar1}, {key=foo2, value=bar2}]

Since your structure does not match, you have two basic options: 由于您的结构不匹配,因此有两个基本选项:

  1. Use two-phase handling: use Jackson to bind into intermediate representation that does match (which could be JsonNode or List<Map<String,Object>> ), and then do conversion to desired type with simple code 使用两阶段处理:使用Jackson绑定到确实匹配的中间表示形式(可以是JsonNodeList<Map<String,Object>> ),然后使用简单的代码转换为所需的类型
  2. Write custom serializer and/or deserializer 编写自定义序列化器和/或反序列化器

Jackson does not support extensive structural transformations (there are some simple ones, like @JsonUnwrapped ), so this kind of functionality is unlikely to be added to databind module. Jackson不支持广泛的结构转换(有一些简单的转换,例如@JsonUnwrapped ),因此这种功能不太可能添加到databind模块中。 Although it could be added as an extension module, if these "smart Map" types of structures are commonly used (they seem to be, unfortunately). 尽管可以将其添加为扩展模块,但是如果通常使用这些“智能地图”类型的结构(不幸的是,它们似乎是)。

Had the same problem and was surprised Jackson wasn't able to natively handle it.有同样的问题,很惊讶 Jackson 无法本地处理它。 Solution I went with was to create a custom setter on the object I was trying to marshal into:我采用的解决方案是在我试图编组的 object 上创建一个自定义设置器:

public class somePojo {
  private Map<String, String> mapStuff;

  ...

  public void SetMapStuff(List<Map<String, String> fromJackson){
    mapStuff= new HashMap<>();
    for (Map<String, String> pair : fromJackson) {
      put(pair.get("key"), pair.get("value"));
    }
  }
}

Jackson is smart enough to find that setter to and can happily pass it the List. Jackson 足够聪明,可以找到该 setter 并愉快地将其传递给 List。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM