杰克逊:[key:value,key:value2]到[key:[value1,value2]]

时间:2016-06-20 06:36:20

标签: java json serialization jackson

我的实体Entcollection<FacetValue>

public class Ent
{
    private List<FacetValue> facets;
}

每个FacetValue都像:

public class FacetValue
{
    private String facetName;
    private String facetValue;

    // getters & setters
}

我需要对这些集合进行de / serialize。为此,我使用JsonSerializer序列化每个对象:

public class FacetValueSerializer extends JsonSerializer<FacetValue>
{

    @Override
    public void serialize(FacetValue value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException
    {

        gen.writeStartObject();
            gen.writeObjectField(value.getKey(), value.getValue());
        gen.writeEndObject();

    }

}

并且,Ent对象的序列化:

public EntSerializer extends JsonSerializer<Ent> 
{
     @Override
     public void serialize(Ent ent, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException
     {
         //...
         gen.writeFieldName("facets");
         gen.writeStartArray(value.getMetainfos().size());
         for (FacetValue facetValue : value.getFacets())
             gen.writeObject(facetValue);
         gen.writeEndArray();
     }
}

因此,您可以理解每个FacetValue基本上是key:"object"对。

问题:     每个键可以有多个值。它们存储在Ent对象中的方式如下:ent.getFacets.add(new FacetValue("k1", "v1"))ent.getFacets.add(new FacetValue("k1", "v2")) ...

因此,在序列化Ent对象后,我会生成一个类似{"facets":[{"k1":"v1"},{"k1":"v2"}]}的json。我想得到:{"facets":[{"k1":["v1", "v2"]}]}

我无法更改Ent设计。我只能更改序列化程序和反序列化程序。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

在序列化程序中,我创建了一个Map,它保存具有相同键的值(使用Java 8流)

public class EntSerializer extends JsonSerializer<Ent>
{
    @Override
    public void serialize(Ent ent, JsonGenerator gen, SerializerProvider serializers)
            throws IOException, JsonProcessingException
    {
        // ...
        gen.writeFieldName("facets");
        gen.writeStartArray(ent.getFacets().size());

        Map<String, List<FacetValue>> facetsByKey = 
                ent.getFacets().stream().collect(Collectors.groupingBy(FacetValue::getKey));
        for (Map.Entry<String, List<FacetValue>> entry : facetsByKey.entrySet()) {
            if (entry.getValue().size() == 1) {
                // generate {"k1":"v1"}
                gen.writeObject(entry.getValue().get(0));
            } else {
                // generate {"k1":["v1", "v2"]}
                gen.writeArrayFieldStart(entry.getKey());
                for (FacetValue facet : entry.getValue()) {
                    gen.writeString(facet.getValue());
                }
                gen.writeEndArray();
            }
        }

        gen.writeEndArray();
    }
}