【发布时间】:2016-02-19 16:43:51
【问题描述】:
鉴于 MyClass2 扩展了 MyClass1 并且只是向 MyClass1 添加了两个属性,我为这两个类编写了两个 Jackson 自定义序列化器,如下所示:
public class MyClass1Serializer extends JsonSerializer<MyClass1> {
@Override
public void serialize(MyClass1 myClass1, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("ApplicationName", myClass1.getApplicationName());
jsonGenerator.writeStringField("UserName", myClass1.getUserName());
}
}
和
public class MyClass2Serializer extends JsonSerializer<MyClass2> {
@Override
public void serialize(MyClass2 myClass2, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("ApplicationName", myClass2.getApplicationName());
jsonGenerator.writeStringField("ErrorMessage", myClass2.getErrorMessage());
jsonGenerator.writeStringField("ResultCode", myClass2.getResultCode());
jsonGenerator.writeStringField("UserName", myClass2.getUserName());
}
}
效果很好,并给我以下输出:
{"ApplicationName":"FakeApp","UserName":"Joe the Schmoe"}
{"ApplicationName":"AnotherApp","ErrorMessage":"Uh oh!","ResultCode":"Errrrm,不好...","UserName":"John Doe"}
嗯,对我来说,两个序列化方法中似乎存在代码重复,我可以从第一个序列化器继承第二个序列化器吗?嗯……
嗯,嗯,我试过了:
public class MyClass1Serializer<T extends MyClass1> extends JsonSerializer<MyClass1> {
@Override
public void serialize(MyClass1 myClass1, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("ApplicationName", myClass1.getApplicationName());
jsonGenerator.writeStringField("UserName", myClass1.getUserName());
}
}
和
public class MyClass2Serializer extends MyClass1Serializer<MyClass2> {
public void serialize(MyClass2 myClass2, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
super.serialize(myClass2, jsonGenerator, serializerProvider);
jsonGenerator.writeStringField("ErrorMessage", myClass2.getErrorMessage());
jsonGenerator.writeStringField("ResultCode", myClass2.getResultCode());
}
}
编译并运行,但给了我这个输出:
{"ApplicationName":"FakeApp","UserName":"Joe the Schmoe"}
{"ApplicationName":"AnotherApp","UserName":"John Doe"}
我很清楚 MyClass2Serializer 现在完全被忽略了,Jackson 找到了 MyClass1Serializer 并将其用于 MyClass2。 (因为它不直接继承 JsonSerializer?)
考虑到这种简单的情况,没什么大不了的,但我在工作中的实际类结构可以通过将自定义序列化程序“链接”在一起而不是从头开始每个序列化程序而真正受益。
为了以防万一,我通过类上的注释告诉杰克逊哪个序列化器用于哪个类:
@JsonSerialize(using=MyClass1Serializer.class)
public class MyClass1 {
未来可能的问题:假设子类化自定义序列化器甚至是可能的,那么子类化自定义反序列化器也可以工作吗?指向一些示例代码或教程的指针会很棒!
【问题讨论】:
-
我试图复制问题,但我从杰克逊那里得到运行时异常:“Class MyClass1Serializer 没有默认(无 arg)构造函数”
-
您是否在主类中为序列化程序使用非静态内部类?那就是我开始的地方,我也遇到了这个错误。您可以将它们设为静态类,也可以将它们移到主类之外(这就是我所做的)。
-
你是对的。我忘了将内部类设为静态