【问题标题】:How to serialize json to Map?如何将json序列化为Map?
【发布时间】:2021-10-02 13:14:29
【问题描述】:

我需要将 json 序列化为 Map。我儿子长这样:

{
   items: [{
      "name": "Test1",
      "value": {
         "id": 1,
         "count": 5
      }
   }]
}

我有以下课程:

public class Value {
    public int id;
    public int count;
}
public class ItemManager {
    public Map<String, Value> items;
}

我试图像这样反序列化它:

class Main {
    public static void main(String... args) {
        ObjectMapper mapper = new ObjectMapper();
        ItemManager manager = mapper.read(args[0], ItemManager.class);
    }
}

但我得到以下异常:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `test.ItemManager` out of START_ARRAY token
 at [Source: (String)"{

我需要将name 作为键,value 作为值。 有人可以帮忙吗?

【问题讨论】:

  • 你没有为别人做任何事情。
  • 你不想要一个地图,你想要一个项目列表,其中每个项目都有一个属性字符串名称和一个属性值值。
  • @ScottHunter 因为我不知道该怎么做
  • 你显然不知道怎么做所有;你知道怎么做任何吗?
  • “上帝帮助那些自助的人”:如果你不愿意为解决这个问题做出任何努力,我为什么要这样做?

标签: java jackson jackson-databind


【解决方案1】:

这是一个简单的自定义反序列化器,可以做你想做的事情(我用过 Jackson v2.12.4):

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import java.io.IOException;

public class ItemManagerDeserializer extends StdDeserializer<ItemManager> {

    public ItemManagerDeserializer() {
        this(null);
    }

    public ItemManagerDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public ItemManager deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        JsonNode node = jp.getCodec().readTree(jp);
        ObjectCodec mapper = jp.getCodec();

        ItemManager itemManager = new ItemManager();
        for (JsonNode element : node.get("items")) {
            String key = element.get("name").asText();
            ItemManager.Value value = mapper.treeToValue(element.get("value"), ItemManager.Value.class);
            itemManager.getItems().put(key, value);
        }

        return itemManager;
    }
} 

我在ItemManager 类中创建了一个静态Value 类,并在构造函数(new HashMap&lt;&gt;()) 中实例化了items 属性。

然后,你可以像这样注册和使用这个反序列化器:

public static void main(String[] args) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addDeserializer(ItemManager.class, new ItemManagerDeserializer());
    mapper.registerModule(module);

    ItemManager itemManager = mapper.readValue(args[0], ItemManager.class);
    itemManager.getItems().forEach((key, value) -> System.out.println("key: " + key + ", value: " + value));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-10
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    • 1970-01-01
    • 2011-08-20
    • 2014-10-16
    相关资源
    最近更新 更多