跳到主要内容

向 Jackson 的 ObjectMapper 添加自定义序列化器和反序列化器

DeepSeek V3 中英对照 Adding Custom Serializers and Deserializers to Jackson’s ObjectMapper Adding Custom Serializers and Deserializers to Jackson’s 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;
}
java

在默认配置中,当向导出器 POST 新数据时,Jackson 不知道要实例化哪个类。您需要通过注解或更简洁地通过使用 Module 注册类型映射来告诉 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));
}
}
java

一旦你在 Module 中获得了 SetupContext 对象的访问权限,你就可以做各种很酷的事情来配置 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);
}
}
java

得益于前面示例中展示的自定义模块,当您的领域对象过于复杂,超出了 Spring Data REST 试图覆盖的 80% 通用用例时,Spring Data REST 能够正确处理这些对象。