使用复杂键从json到java的hashmap

ao218c7q  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(411)

我目前正在开发一个应用程序,其中我需要序列化 HashMap<Object1, Object2> 转换为json,然后从json反序列化到同一个“hashmap”。
我能够序列化它使用通常的Map器和覆盖 toString() 方法 Object1 .

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

然后我就可以序列化并获得预期的json(res是我之前定义的字符串,不必全部写回去)*

{res : Object2JsonRepresentation}

然后我想反序列化,所以我使用一个自定义的keydeserializer:

@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;
    }
}

尽管如此 keyDeserializer 好像从来没人打过电话,你能解释一下原因吗。我对json还很陌生,如果能给出详细的答案,我会很高兴的。

js81xvg6

js81xvg61#

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

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

在这种情况下,序列化程序和反序列化程序将如下所示:

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创建类(用于检查不同类型的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"
  }
}

相关问题