使用复杂密钥的json到java hashmap

时间:2017-01-04 09:49:21

标签: java json hashmap key deserialization

我目前正在开发一个应用程序,我需要序列化一个 将HashMap<Object1, Object2>转换为JSON,然后从JSON反序列化为相同的`HashMap'。

我可以使用常用的映射器对其进行序列化,并覆盖toString()的{​​{1}}方法。

Object1

然后我能够序列化并获得预期的json(其中res是我之前定义的字符串,更容易不写回来)。*

public String toString(){
    String res = Object1.elem1 + ";" + Object1.elem2;
    return res
}

然后我想反序列化,所以我使用自定义keyDeserializer:

{res : Object2JsonRepresentation}

@XmlElement(name="myMap") @JsonDeserialize(keyUsing = Object1KeyDeserializer.class) public HashMap <Object1,Object2> myMap = new HashMap <>();

Object1KeyDeserializer

尽管如此,public class Object1KeyDeserializer extends KeyDeserializer{ @Override public Object1 deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException { String[] parts = key.split(";"); System.out.println(key); Elem elem1 = new Elem(parts[1]); Elem elem2 = new Elem(parts[2]); Object1 obj = new Object1(elem1,elem2); return obj; } } 似乎永远不会被召唤,你能解释一下原因吗?我对JSON很陌生,如果答案可以详细说明,我会很高兴。

1 个答案:

答案 0 :(得分:0)

您可以创建自己的序列化格式,而不是使用toString()。如果Map中有非原始键,则可以将Map序列化为

[
    {
        "key": <serialized key>,
        "value: <serialized value>
    },
    ....
]

在这种情况下,您的Serializer和Deserializer将遵循:

public class CustomSerializer extends StdSerializer<Map<Object1, Object2>> {

    protected CustomSerializer() {
        super(Map.class, true);
    }

    @Override
    public void serialize(Map<Object1, Object2> map,
                          JsonGenerator jsonGenerator,
                          SerializerProvider serializerProvider) throws IOException{

        jsonGenerator.writeStartArray();
        for (Map.Entry<Object1,Object2> element: map.entrySet()) {
            jsonGenerator.writeStartObject();
            jsonGenerator.writeObjectField("key", element.getKey());
            jsonGenerator.writeObjectField("value", element.getValue());
            jsonGenerator.writeEndObject();
        }
        jsonGenerator.writeEndArray();
    }
}

public class CustomDeserializer extends StdDeserializer<Map<Object1, Object2>> {
    protected CustomDeserializer() {
        super(Map.class);
    }

    @Override
    public Map<Object1, Object2> deserialize(JsonParser jsonParser,
                                             DeserializationContext deserializationContext) throws IOException {
        Map<Object1, Object2> result = new HashMap<>();
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        for (JsonNode element : node) {
            result.put(
                    jsonParser.getCodec().treeToValue(element.get("key"), Object1.class),
                    jsonParser.getCodec().treeToValue(element.get("value"), Object2.class)
            );
        }
        return result;
    }
}

因此,您可以使用您的字段和另一个Map创建类(用于检查具有不同类型的地图照常工作):

public class MapWrapper {

    @JsonSerialize(using = CustomSerializer.class)
    @JsonDeserialize(using = CustomDeserializer.class)
    private Map<Object1, Object2> map = new HashMap<>();

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

    // default constructor, getters, setters
}

序列化值可以是:

{
  "map": [
    {
      "key": {
        "elem1": "qqq",
        "elem2": "rrr"
      },
      "value": {
        "fieldFromValue": "xxx"
      }
    },
    {
      "key": {
        "elem1": "qqq_two",
        "elem2": "rrr_two"
      },
      "value": {
        "fieldFromValue": "yyy"
      }
    }
  ],
  "someMap": {
    "key1": "value1"
  }
}