Java/ jackson : Deserialize JSON into class with HashMap

标签 java json hashmap jackson deserialization

我想反序列化以下 JSON 输入:

{
  "key1": "value1",
  "key2": "value2"
}

进入包含 HashMap 的类对象:

public class ClassContainingMap {

  private Map<String, String> map = new HashMap<>();

  public Map<String, String> getMap() {
     return map;
  }

  public void setMap(Map<String, String> map) {
     this.map = map;
  }
}

执行时

ClassContainingMap m = objectMapper.readValue(json, ClassContaininMap.class);

我明白了

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of test.ClassContainingMap: no Stri
ng-argument constructor/factory method to deserialize from String value ('key1')
 at [Source: "key1": "value1", "key2": "value2"; line: 1, column: 1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
    at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1012)
    at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:370)
    at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:315)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1283)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:150)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3814)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2858)

我发现当用@JsonValue注释getter时我可以得到另一个方向(序列化)工作,但到目前为止我还无法弄清楚反序列化的问题。有没有简单的(注释?)方法可以实现这一点,而无需编写自定义反序列化器?

最佳答案

您没有提供如何使用 @JsonValue 注释的示例,因此我可能错过了一些内容,但无论如何。

当序列化时,我认为你会做类似的事情:

ClassContainingMap ccm = new ClassContainingMap();
ccm.getMap().put("key1", "value1");
ccm.getMap().put("key2", "value2");

System.out.println(om.writeValueAsString(ccm)); 

这将起作用并生成以下 JSON:

{
    "map": {
        "key1":"value1",
        "key2":"value2",
    }
}

但这并不等于您想要读取到ClassContainingMap的JSON结构:

{
    "key1": "value1",
    "key2": "value2"
}

也就是说,前者是来自 ClassContainingMap 的数据,而后者是我认为您想要在 ClassContainingMap 中填充的“唯一”Map

您有两个选项可供选择;

  1. 使用正确的 JSON 结构作为对应于 ClassContainingMap 的源
  2. 只需将其反序列化为一个简单的 map ,例如:

    Map map = om.readValue(i, Map.class);
    
  3. 如果以上任一方法可行,一种方法是使用 @JsonCreator

    @JsonCreator(mode=Mode.DELEGATING)
    public ClassContainingMap(@JsonProperty("map")Map<String,String> map) {
        this.map = map;
    }
    
    @JsonValue
    public Map<String, String> getMap() {
        return map;
    }
    

查看有关 3rd 的更多信息,例如 here

关于Java/ jackson : Deserialize JSON into class with HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52190384/

相关文章:

java - 应用程序中的 webview 是否缓存页面?

java - 模块依赖Java解释

java - 在这些行中查找特定模式的正确正则表达式是什么?

javascript - Angular $filter 用于在 JSON 响应内的数组中进行深度过滤

javascript - 为什么对我的 Controller 的调用不起作用?

javascript - django queryset to json列表到js数组

java - 使用流从字符串列表创建映射

java - 了解 HashMap 和 IdentityHashMap

android - 在android中的edittext中使用spannable

java - 我可以使用 Spring Integration 通过 RabbitMQ 进行同步/阻塞调用吗?