如何在地图地图中使用jackson密钥序列化程序

时间:2016-11-01 01:21:27

标签: java json serialization jackson

我正在尝试使用Jackson 2.5将Java对象结构序列化为JSON,并且我遇到了关键序列化器的以下问题:

class MainContainer {
    private final Map<String, Object> entries;
}

class Item {
    // a lot of attributes
}

class ItemMapKeySerializer extends JsonSerializer<Item> {
     // serialize an item into something simple for map keys
}

class IntermediateContainer {
     private final Map<Item, ... > someMapping;
}

我在ObjectMapper中将ItemMapKeySerializer注册为SimpleModule。当我将ItermediateContainer添加到MainContainer时,使用ItemMapKeySerializer。当我将带有Item作为键的Map直接添加到MainContainer中时,不使用ItemMapKeySerializer,我不确定原因。

此代码:

MainContainer.add("test", new IntermediateContainer(Map.of(new Item(), ...)));

导致这个JSON:

 entries: {
    "test": {
        someMapping: {
            "my nice item 1": {
            ...
            }             
        }
    }
}

这段代码:

MainContainer.add("test", Map.of(new Item(), ...));

导致这个JSON:

 entries: {
    "test": {
        Item@12D23: {  // This kind of fieldname is not desired
        ...
        }             
    }
}

因此,当我在Map中使用Map作为值时,键序列化器不会使用,但这就是我想要发生的事情。有谁知道如何做到这一点?

谢谢, 本尼

2 个答案:

答案 0 :(得分:0)

您应该在项目中添加“toString()”方法。例如,我检查了这个例子:

public static class Item {
    private String val1;
    private int val2;

    public Item(String val1, int val2) {
        this.val1 = val1;
        this.val2 = val2;
    }

    @Override
    public boolean equals(Object obj) {
        return obj instanceof Item && toString().equals(obj.toString());
    }

    @Override
    public int hashCode() {
        return toString().hashCode();
    }

    @Override
    public String toString() {
        return "val1=" + val1 + ",val2=" + val2;
    }
}

这为我提供了一个简单地图的JSON字符串,其中Item(“AAA”,123)指向“Super!”:

{"val1=AAA,val2=123":"Super!"}

您甚至可以更进一步,使用Item.toString中的ObjectMapper.writeValueAsString为关键文本生成Item的JSON表示。

答案 1 :(得分:0)

从2.5到2.8升级到Jackson-databind解决了这个问题,并为嵌套地图正确选取了关键序列化器。