让jackson序列化apache commons Pair

时间:2017-07-04 12:02:42

标签: java json jackson apache-commons

如果没有制作我自己的org.apache.commons.lang3.tuple.Pair复杂序列化器,我怎样才能制作杰克逊,以正确的方式序列化我的左右对象。所以例如我必须遵循以下代码:

 public class MyPairTest {

    public static void main(String[] args) {
        Address address1 = new Address("Axel Street 1", "London");
        Address address2 = new Address("Axel Street 2", "Copenhagen");

        Map<String, Pair> map = new HashMap<>();
        map.put("Address", Pair.of(address1, address2));

        Pair p = Pair.of(address1, address2);

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
            String serializeMapWithPair = mapper.writeValueAsString(map);
            String serializePair = mapper.writeValueAsString(p);
            System.out.println(serializeMapWithPair);
            System.out.println(serializePair);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        Gson gson = new Gson();
        System.out.println(gson.toJson(p));
    }
}

结果输出为:

{
  "Address" : {
    "com.example.api.beans.Address@224edc67" : {
      "street" : "Axel Street 2",
      "city" : "Copenhagen"
    }
  }
}
{
  "com.example.api.beans.Address@224edc67" : {
    "street" : "Axel Street 2",
    "city" : "Copenhagen"
  }
}
{"left":{"street":"Axel Street 1","city":"London"},"right":{"street":"Axel Street 2","city":"Copenhagen"}}

所以前两个输出正在使用jackson ObjectMapper序列化Pair,其中最后一个是Gson,我希望在Gson示例中实现结果,但是使用jackson并且没有leftright部分。我从this jira improvement suggestion获得的Gson示例,我知道他们说明了以下"Commons-lang has no dependencies, so Jackson or anything similar can not be used."但是想知道杰克逊是否自己制作了一个序列化器或类似的,找不到类似的东西那么杰克逊可能没有简单的解决方案吗?或者我应该放弃它并使用Gson,然后只需手动操作并删除leftright部分?

3 个答案:

答案 0 :(得分:1)

无论如何,我认为我将继续使用前后字段实现我自己的泛型类,然后序列化它,甚至可以实现我最终的结果,所以我最终得到类似下面的类:

public class MyPair<T> {
    private T before;
    private T after;

    private MyPair(T before, T after) {
        this.before = before;
        this.after = after;
    }

    public static <T> MyPair<T> of(final T before, final T after) {
        return new MyPair<>(before, after);
    }

    public T getBefore() {
        return this.before;
    }

    public T getAfter() {
        return this.after;
    }

    public void setBefore(T before) {
        this.before = before;
    }

    public void setAfter(T after) {
        this.after = after;
    }
}

然后我可以调用MyPair.of(address1, address2)并将其序列化为

{
  "Address" : {
    "before" : {
      "street" : "Axel Street 1",
      "city" : "London"
    },
    "after" : {
      "street" : "Axel Street 2",
      "city" : "Copenhagen"
    }
  }
}

这是我所期待的:)。只需要确保使用相同的对象类型调用它,否则抛出编译时错误,似乎不起作用,因为现在of()可以用两种不同的类型调用。

答案 1 :(得分:1)

要详细回答问题,

Jackson将Pair<K,V> implements Map.Entry<K,V>视为地图的一项,并生成错误的输出。

唯一的绕过方法是编写自己的Pair类,该类从不实现Map.Entry接口。

答案 2 :(得分:1)

您可以编写自定义序列化器:

private static final class PairSerializer extends JsonSerializer<Pair> {

    @Override
    public void serialize(Pair value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        gen.writeObjectField("left", value.getLeft());
        gen.writeObjectField("right", value.getRight());
        gen.writeEndObject();
    }

}

并在您的ObjectMapper中注册它:

mapper.registerModule(new SimpleModule().addSerializer(Pair.class, new PairSerializer()));