如何在单个ObjectMapper实例中为指定包配置Jackson集合序列化规则?
单个ObjectMapper实例实现特定包下集合/Map的空值不序列化
可以实现,无需多个ObjectMapper实例,下面提供两种可行方案:
方案一:自定义AnnotationIntrospector
通过扩展Jackson的JacksonAnnotationIntrospector,根据字段所属类的包路径,动态设置集合/Map类型字段的序列化包含规则。
实现步骤
- 定义自定义Introspector类:
public class PackageSpecificIncludeIntrospector extends JacksonAnnotationIntrospector { private static final String TARGET_PACKAGE_PREFIX = "com.mycompany."; private static final String GENERATED_PACKAGE_MARKER = ".generated."; private final JsonInclude.Value NON_EMPTY_NON_NULL = JsonInclude.Value.construct( JsonInclude.Include.NON_EMPTY, JsonInclude.Include.NON_NULL ); @Override public JsonInclude.Value findPropertyInclusion(AnnotatedMember member) { Class<?> declaringClass = member.getDeclaringClass(); String className = declaringClass.getName(); // 校验类是否属于目标包范围 if (className.startsWith(TARGET_PACKAGE_PREFIX) && className.contains(GENERATED_PACKAGE_MARKER)) { Class<?> propertyType = member.getRawType(); // 仅对集合/Map类型字段应用规则 if (Collection.class.isAssignableFrom(propertyType) || Map.class.isAssignableFrom(propertyType)) { return NON_EMPTY_NON_NULL; } } // 其他情况沿用默认规则 return super.findPropertyInclusion(member); } }
- 将自定义Introspector注册到ObjectMapper:
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setAnnotationIntrospector(new PackageSpecificIncludeIntrospector());
方案二:使用BeanSerializerModifier
通过自定义BeanSerializerModifier,在序列化前修改目标包类中集合/Map字段的序列化规则。
实现步骤
- 定义自定义SerializerModifier类:
public class PackageSpecificSerializerModifier extends BeanSerializerModifier { private static final String TARGET_PACKAGE_PREFIX = "com.mycompany."; private static final String GENERATED_PACKAGE_MARKER = ".generated."; private final JsonInclude.Value NON_EMPTY_NON_NULL = JsonInclude.Value.construct( JsonInclude.Include.NON_EMPTY, JsonInclude.Include.NON_NULL ); @Override public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) { Class<?> beanClass = beanDesc.getBeanClass(); String className = beanClass.getName(); if (className.startsWith(TARGET_PACKAGE_PREFIX) && className.contains(GENERATED_PACKAGE_MARKER)) { for (BeanPropertyWriter writer : beanProperties) { Class<?> propType = writer.getType().getRawClass(); if (Collection.class.isAssignableFrom(propType) || Map.class.isAssignableFrom(propType)) { // 为目标字段设置空值不序列化规则 writer.setInclusion(NON_EMPTY_NON_NULL); } } } return super.changeProperties(config, beanDesc, beanProperties); } }
- 注册到ObjectMapper:
ObjectMapper objectMapper = new ObjectMapper(); SimpleModule customModule = new SimpleModule(); customModule.setSerializerModifier(new PackageSpecificSerializerModifier()); objectMapper.registerModule(customModule);
注意事项
- 请移除原来全局的
configOverride配置,避免与自定义规则冲突。 - 两种方案均通过动态判断类的包路径来选择性应用规则,完全基于单个ObjectMapper实例实现。
内容的提问来源于stack exchange,提问作者bilak
相关产品推荐
相关产品推荐

