将自定义序列化器和反序列化器添加到 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 会正确处理您的域对象。