向 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;
}
在默认配置中,Jackson 在向导出器 POST 新数据时不知道要实例化哪个类。您需要通过注解或更简洁地通过使用 模块 注册类型映射来告知 Jackson。
在您的 ApplicationContext 范围内声明的任何 Module 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));
}
}
一旦您在 Module 中访问了 SetupContext 对象,您就可以执行各种很酷的操作来配置 Jackon 的 JSON 映射。您可以阅读有关 模块在 Jackson wiki 上的工作原理 的更多信息。
为领域类型添加自定义序列化器
如果您想以特殊方式序列化或反序列化领域类型,您可以向 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 能够正确处理它们。