让杰克逊序列化apache commons Pair
Make jackson serialize apache commons Pair
我怎样才能使 jackson 以正确的方式同时序列化我的左对象和右对象?因此,例如我必须遵循以下代码:
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 而没有 left
和 right
部分。我从 this jira improvement suggestion 得到的 Gson
例子,我知道他们陈述了以下内容 "Commons-lang has no dependencies, so Jackson or anything similar can not be used."
但是想知道 Jackson 是否自己制作了一个序列化器或类似的东西,找不到类似的东西在那里,也许杰克逊没有简单的解决方案?或者我应该放弃它并使用 Gson,然后手动操作并删除 left
和 right
部分?
无论如何,我认为我会用一个 before 和 after 字段来实现我自己的通用 class 然后序列化它,甚至按照我想要的方式工作,所以我结束了类似下面的内容 class:
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()
可以用两种不同的类型调用。
详细回答问题:
Jackson 将 Pair<K,V> implements Map.Entry<K,V>
视为地图的一项并生成错误的输出。
绕过的唯一方法是编写您自己的 Pair
class,它永远不会实现 Map.Entry
接口。
您可以编写自定义序列化程序:
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()));
我怎样才能使 jackson 以正确的方式同时序列化我的左对象和右对象?因此,例如我必须遵循以下代码:
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 而没有 left
和 right
部分。我从 this jira improvement suggestion 得到的 Gson
例子,我知道他们陈述了以下内容 "Commons-lang has no dependencies, so Jackson or anything similar can not be used."
但是想知道 Jackson 是否自己制作了一个序列化器或类似的东西,找不到类似的东西在那里,也许杰克逊没有简单的解决方案?或者我应该放弃它并使用 Gson,然后手动操作并删除 left
和 right
部分?
无论如何,我认为我会用一个 before 和 after 字段来实现我自己的通用 class 然后序列化它,甚至按照我想要的方式工作,所以我结束了类似下面的内容 class:
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()
可以用两种不同的类型调用。
详细回答问题:
Jackson 将 Pair<K,V> implements Map.Entry<K,V>
视为地图的一项并生成错误的输出。
绕过的唯一方法是编写您自己的 Pair
class,它永远不会实现 Map.Entry
接口。
您可以编写自定义序列化程序:
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()));