配置Jackson序列化/反序列化以兼容Immutables类
配置Jackson自动适配Immutables类
不需要给每个带@Value.Immutable的接口手动添加@JsonDeserialize和@JsonSerialize注解,你可以通过自定义Jackson Module实现自动绑定对应的Immutable实现类,具体步骤如下:
1. 实现自定义类型解析器
这个解析器负责检测带有@Value.Immutable注解的抽象类型,并找到对应的Immutable实现类:
import com.fasterxml.jackson.databind.AbstractTypeResolver; import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.SerializationConfig; import org.immutables.value.Value; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; public class ImmutablesTypeResolver extends AbstractTypeResolver { @Override public Class<?> findTypeMapping(SerializationConfig config, BeanDescription typeDesc) { return findImmutableImpl(typeDesc.getBeanClass()); } @Override public Class<?> findTypeMapping(DeserializationConfig config, BeanDescription typeDesc) { return findImmutableImpl(typeDesc.getBeanClass()); } private Class<?> findImmutableImpl(Class<?> abstractType) { // 仅处理带有@Value.Immutable注解的类型 if (!abstractType.isAnnotationPresent(Value.Immutable.class)) { return null; } String simpleName = abstractType.getSimpleName(); String implSimpleName = "Immutable" + simpleName; String implClassName; // 处理内部类和普通类的类名拼接 if (abstractType.isMemberClass()) { implClassName = abstractType.getName().replace(simpleName, implSimpleName); } else { implClassName = abstractType.getPackage().getName() + "." + implSimpleName; } try { Class<?> implClass = Class.forName(implClassName); // 验证实现类的合法性:是抽象类型的子类、且为final类(Immutables生成类的特征) if (abstractType.isAssignableFrom(implClass) && Modifier.isFinal(implClass.getModifiers())) { // 检查是否有私有构造器(Immutables生成类的构造器为私有,通过builder创建) for (Constructor<?> c : implClass.getDeclaredConstructors()) { if (Modifier.isPrivate(c.getModifiers())) { return implClass; } } } } catch (ClassNotFoundException e) { // 找不到实现类时返回null,Jackson将按默认逻辑处理 return null; } return null; } }
2. 创建自定义Jackson Module
将上面的类型解析器注册到Module中:
import com.fasterxml.jackson.databind.module.SimpleModule; public class ImmutablesJacksonModule extends SimpleModule { public ImmutablesJacksonModule() { super("ImmutablesJacksonModule"); addAbstractTypeResolver(new ImmutablesTypeResolver()); } }
3. 注册Module到ObjectMapper
在配置Jackson的ObjectMapper时,注册这个自定义Module:
import com.fasterxml.jackson.databind.ObjectMapper; public class JacksonConfig { public static ObjectMapper createObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); // 注册Immutables自动适配模块 objectMapper.registerModule(new ImmutablesJacksonModule()); // 可添加其他Jackson配置,比如忽略未知属性 objectMapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return objectMapper; } }
注意事项
- 确保项目已正确配置Immutables注解处理器,编译时能生成
ImmutableXxx实现类 - 若接口存在嵌套类结构,上述代码已处理
Outer.Foo对应Outer.ImmutableFoo的情况 - 如果实现类的命名规则不是
Immutable+原类名,需要调整implSimpleName的生成逻辑
内容的提问来源于stack exchange,提问作者Mark Elliot
相关产品推荐
相关产品推荐

