背景
在springboot-web项目中,绝大多时候都是使用json格式来传输数据,springboot默认使用jackson来转换,一般情况下,默认的转化设置已经可以满足要求。特殊一点的使用Jackson相关的注解辅助也能完成。
但是在一次开发过程中,要求对某些字段进行加解密,但是由于是spring微服务的项目,所以只在其中一个服务中需要加密,所以没有办法使用@JsonSerialize 和 @JsonDeserialize着两种jackson的注解。
解决思路
一开始想的是,jackson既然实现了自己的注解,那它为了满足用户的需求,肯定做了兼容让用户根据自己的需要做数据的转换。经过查询资料和源码,发现OjectMapper有一个注入内省注解处理器的方法:
public ObjectMapper setAnnotationIntrospector(AnnotationIntrospector ai) {
_serializationConfig = _serializationConfig.with(ai);
_deserializationConfig = _deserializationConfig.with(ai);
return this;
}
public ObjectMapper setAnnotationIntrospectors(AnnotationIntrospector serializerAI,
AnnotationIntrospector deserializerAI) {
_serializationConfig = _serializationConfig.with(serializerAI);
_deserializationConfig = _deserializationConfig.with(deserializerAI);
return this;
}
序列化
ObjectMapper在对象序列化时,会使用到 _serializationConfig这个配置。
protected final void _configAndWriteValue(JsonGenerator g, Object value)
throws IOException
{
SerializationConfig cfg = getSerializationConfig(); //这个方法会返回 包含了 自定义注解解释类的的 _serializationConfig
cfg.initialize(g); // since 2.5
if (cfg.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) {
_configAndWriteCloseable(g, value, cfg);
return;
}
try {
// _serializerProvider(cfg) 会构建一个默认的 DefaultSerializerProvider序列化对象
_serializerProvider(cfg).serializeValue(g, value);
} catch (Exception e) {
ClassUtil.closeOnFailAndThrowAsIOE(g, e);
return;
}
g.close();
}
DefaultSerializerProvider继承了SerializerProvider
public JsonSerializer