Java / Jackson:使用HashMap将JSON反序列化为类

Java/Jackson: Deserialize JSON into class with HashMap

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

1
2
3
4
{
 "key1":"value1",
 "key2":"value2"
}

放入包含哈希映射的类对象中:

1
2
3
4
5
6
7
8
9
10
11
12
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;
  }
}

执行

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

我得到

1
2
3
4
5
6
7
8
9
10
11
12
13
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注释吸气剂时,我可以得到另一个方向(序列化)的工作,但是到目前为止,我还无法弄清楚反序列化的原因。是否有任何简单的方法(注释?)来实现此目的,而不必编写自定义解串器?


您没有提供如何使用@JsonValue批注的示例,因此我可能还是错过了一些东西。

序列化时,我认为您可以执行以下操作:

1
2
3
4
5
ClassContainingMap ccm = new ClassContainingMap();
ccm.getMap().put("key1","value1");
ccm.getMap().put("key2","value2");

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

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

1
2
3
4
5
6
{
   "map": {
       "key1":"value1",
       "key2":"value2",
    }
}

但这不等于您要读取为ClassContainingMap的JSON结构:

1
2
3
4
{
   "key1":"value1",
   "key2":"value2"
}

即,前者是来自ClassContainingMap的数据,而后者是"仅" Map,我想您要在ClassContainingMap中填充。

您可以检查两个选项;

  • 使用正确的JSON结构作为与ClassContainingMap相对应的源
  • 只需将其反序列化为简单的地图即可,例如:

    1
    Map map = om.readValue(i, Map.class);
  • ,如果以上任何一种可能,则一种方法是使用@JsonCreator

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @JsonCreator(mode=Mode.DELEGATING)
    public ClassContainingMap(@JsonProperty("map")Map<String,String> map) {
        this.map = map;
    }

    @JsonValue
    public Map<String, String> getMap() {
        return map;
    }
  • 例如,在此处查看有关3rd的更多信息