主页传送门: 传送
序列化是将对象转换为字节序列的过程,而反序列化则是将字节序列恢复为对象的过程。在Java中,序列化和反序
列化是通过实现Serializable接口来实现的。当一个类实现了Serializable
接口时,它的对象就可以被序列化和反序列化了 。
序列化最重要的作用是在传递和保存对象时保证对象的完整性和可传递性
如果您使用 Jackson 来序列化和反序列化 JSON 数据,您可能需要编写自己的JsonSerializer
和JsonDeserializer
类。自定义序列化器通常通过 module
向 Jackson 注册。
俩种实现方法:
org.codehaus.jackson.map.JsonSerializedWithType
:这与实现java.lang.Serialized
类似,调用值类的serialize()方法 来处理序列化。
Jackson 1.5
之前,推荐的接口是org.codehaus.jackson.map.ser.SerializerBase
(适用于任何类型)或org.codehaus.jackson.map.ser.ScalarSerializerBase
(适用于输出JSON字符串、布尔值或数字的序列化程序,也称为标量类型)org.codehaus.jackson.map.JsonSerializer
来创建一个外部序列化器,该程序可以注册以处理某些类型的值(或者更具体地说,某些属性的值)使用注释
类和方法可以使用@JsonSerialize.using(将序列化程序类作为参数)进行注释,以指示要使用的序列化程序的类型
使用Jackson 1.7及以上版本
Jackson 1.7添加了通过Module 接口注册序列化器和反序列化的能力。这是添加自定义序列化程序的推荐方法——所有序列化程序都被视为“通用”,因为除非找到更具体的绑定,否则它们都用于子类型。
示例:
ObjectMapper mapper = new ObjectMapper();
SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null));
testModule.addSerializer(new MyCustomSerializer()); // 假设序列化程序声明了要绑定到的正确类
mapper.registerModule(testModule);
为了更高级地处理序列化程序的类型,您可能需要直接实现Module接口;这将提供对精确匹配逻辑的更多控制。在处理泛型类型(尤其是映射和集合)时,这可能是必要的。
Jackson 1.7之前
主要方法:
通过使用自定义序列化程序工厂(org.codehaus.jackson.map.SerizerFactory)
使用或扩展现有的实现,org.codehaus.ackson.map.ser.CustomSerializerFactory
(如果不适用,甚至从头开始实现)
通过调用addSpecificMapping
或addGenericMapping
添加映射(从序列化的Class到JsonSerializer实例)
自定义序列化程序工厂需要向ObjectMapper.setSerializerFactory
注册才能由ObjectMapper
使用
请注意,从1.8开始,CustomSerializerFactory 已被弃用,不应使用。
示例:
// Configuration of ObjectMapper:
{
// First: need a custom serializer provider
StdSerializerProvider sp = new StdSerializerProvider();
sp.setNullValueSerializer(new NullSerializer());
// And then configure mapper to use it
ObjectMapper m = new ObjectMapper();
m.setSerializerProvider(sp);
// Serialization as done using regular ObjectMapper.writeValue()
}
// and NullSerializer can be something as simple as:
public class NullSerializer extends JsonSerializer<Object>
{
public void serialize(Object value, JsonGenerator jgen,
SerializerProvider provider)
throws IOException, JsonProcessingException
{
// any JSON value you want...
jgen.writeString("");
}
}
Spring Boot 提供了另一种 @JsonComponent 注释,可以更容易地直接注册 Spring Beans。
可以直接在 JsonSerializer
或 JsonDeserializer
实现上使用@JsonComponent
注释。您还可以在包含序列化程序/反序列化程序作为内部类的类上使用它
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.jackson.JsonComponent;
@JsonComponent
public class MyJsonComponent {
public static class Serializer extends JsonSerializer<MyObject> {
@Override
public void serialize(MyObject value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
jgen.writeStartObject();
jgen.writeStringField("name", value.getName());
jgen.writeNumberField("age", value.getAge());
jgen.writeEndObject();
}
}
public static class Deserializer extends JsonDeserializer<MyObject> {
@Override
public MyObject deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
ObjectCodec codec = jsonParser.getCodec();
JsonNode tree = codec.readTree(jsonParser);
String name = tree.get("name").textValue();
int age = tree.get("age").intValue();
return new MyObject(name, age);
}
}
}
ApplicationContext
中的所有 @JsonComponent bean
都会自动注册到 Jackson。因为 @JsonComponent
是使用 @Component
进行元注释的,所以通常的组件扫描规则适用。
Spring Boot 还提供了 JsonObjectSerializer
和 JsonObjectDeserializer
基类,它们在序列化对象时提供了标准 Jackson 版本的有用替代方法。有关详细信息,请参阅 Javadoc 中的 JsonObjectSerializer 和 JsonObjectDeserializer 。
如果喜欢的话,欢迎 关注 点赞 评论 收藏 一起讨论 你的支持就是我✍️创作的动力!
序列化反序列化测试用例及替换默认Jackson库源码:
序列化、反序列化测试
参考资料
Spring Boot json官方文档