|
对于最新的稳定版本,请使用 Spring Data REST 5.0.4! |
向 Jackson 的 ObjectMapper 添加自定义序列化器和反序列化器
有时,Spring Data REST 的 ObjectMapper(已特别配置为使用智能序列化器,能够将领域对象转换为链接并可反向还原)可能无法正确处理您的领域模型。您的数据结构方式多种多样,可能会发现自己的领域模型无法正确转换为 JSON。在这些情况下,以通用方式支持复杂的领域模型有时并不现实。有时,根据复杂程度的不同,甚至根本不可能提供一种通用的解决方案。
为了覆盖绝大多数使用场景,Spring Data REST 会尽力正确地渲染您的对象图。它会尝试将非托管的 Bean 作为普通 POJO 进行序列化,并在必要时为托管的 Bean 创建链接。然而,如果您的领域模型不适合直接读写纯 JSON,您可能需要使用自定义的类型映射和(反)序列化器来配置 Jackson 的 ObjectMapper。
抽象类注册
您可能需要介入的一个关键配置点是:当您在领域模型中使用抽象类(或接口)时。默认情况下,Jackson 并不知道应该为某个接口创建哪种具体实现。请考虑以下示例:
@Entity
public class MyEntity {
@OneToMany
private List<MyInterface> interfaces;
}
在默认配置下,当你向导出器(exporter)发送 POST 请求以提交新数据时,Jackson 并不知道应该实例化哪个类。你需要通过注解告诉 Jackson,或者更清晰的方式是,通过使用 Module 注册一个类型映射。
在您的 Module 范围内声明的任何 ApplicationContext bean 都会被导出器自动识别,并注册到其 ObjectMapper 中。要添加这种特殊的抽象类类型映射,您可以创建一个 Module bean,并在其 setupModule 方法中添加一个合适的 TypeResolver,如下所示:
public class MyCustomModule extends SimpleModule {
private MyCustomModule() {
super("MyCustomModule", new Version(1, 0, 0, "SNAPSHOT"));
}
@Override
public void setupModule(SetupContext context) {
context.addAbstractTypeResolver(
new SimpleAbstractTypeResolver().addMapping(MyInterface.class,
MyInterfaceImpl.class));
}
}
一旦你在自己的 SetupContext 中获得了 Module 对象,就可以执行各种酷炫的操作来配置 Jackson 的 JSON 映射。你可以阅读更多关于 Jackson Wiki 上 Modules 的工作原理。
为领域类型添加自定义序列化器
如果你想以特殊方式序列化或反序列化某个领域类型,可以向 Jackson 的 ObjectMapper 注册你自己的实现。这样,Spring Data REST 导出器就能透明地正确处理这些领域对象。
要在您实现的 setupModule 方法中添加序列化器,可以执行如下操作:
public class MyCustomModule extends SimpleModule {
…
@Override
public void setupModule(SetupContext context) {
SimpleSerializers serializers = new SimpleSerializers();
SimpleDeserializers deserializers = new SimpleDeserializers();
serializers.addSerializer(MyEntity.class, new MyEntitySerializer());
deserializers.addDeserializer(MyEntity.class, new MyEntityDeserializer());
context.addSerializers(serializers);
context.addDeserializers(deserializers);
}
}
由于前面示例中所示的自定义模块,当您的领域对象过于复杂、超出了 Spring Data REST 所试图覆盖的 80% 通用使用场景时,Spring Data REST 仍能正确处理这些对象。