
本文介绍如何利用 Jackson 的 @JsonFilter 与 Mix-in 类机制,对任意 Map 进行动态键过滤后生成 JSON,支持运行时灵活指定需排除或保留的键,无需修改原始数据结构。
本文介绍如何利用 jackson 的 `@jsonfilter` 与 mix-in 类机制,对任意 `map
Jackson 默认将 HashMap(及其父类 Object)视为通用容器,不支持直接通过 @JsonFilter 注解生效——因为 Object.class 本身没有声明过滤器。要使过滤逻辑作用于 Map,必须借助 Mix-in 类 为 Object 注入 @JsonFilter 元信息,从而让 Jackson 在序列化任意对象(包括 HashMap)时识别并应用配置的 FilterProvider。
✅ 正确实现步骤
-
定义空 Mix-in 类并标注过滤器名
创建一个无字段、无方法的占位类,并用@JsonFilter声明过滤器标识符(如"filter"):@JsonFilter("filter") public class DynamicMixIn { } -
注册 Mix-in 到 ObjectMapper
将该 Mix-in 绑定到Object.class(而非HashMap.class),因为HashMap继承自Object,且 Jackson 对 Map 的序列化最终委托给泛型处理逻辑:ObjectMapper objectMapper = new ObjectMapper(); objectMapper.addMixIn(Object.class, DynamicMixIn.class);
-
配置动态 FilterProvider
使用SimpleBeanPropertyFilter指定需保留或排除的键。注意:-
filterOutAllExcept(...)→ 仅保留列出的键(白名单); -
serializeAllExcept(...)→ 排除列出的键(黑名单);
两者均支持传入Collection<string></string>,便于运行时动态构建:
// 示例:动态排除 KEY1 和 KEY3 Set<string> keysToExclude = Set.of("KEY1", "KEY3"); FilterProvider filter = new SimpleFilterProvider() .addFilter("filter", SimpleBeanPropertyFilter.serializeAllExcept(keysToExclude)); objectMapper.setFilterProvider(filter);</string> -
-
执行序列化
此时writeValueAsString(hashtable)将严格按过滤规则输出 JSON:Map<string string> hashtable = new HashMap(); hashtable.put("KEY1", "VALUE1"); hashtable.put("KEY2", "VALUE2"); hashtable.put("KEY3", "VALUE3"); String json = objectMapper.writeValueAsString(hashtable); System.out.println(json); // 输出: {"KEY2":"VALUE2"}</string>
⚠️ 关键注意事项
-
Mix-in 必须绑定到
Object.class:绑定到HashMap.class无效,因 Jackson 对Map的序列化不走标准 Bean 处理流程,而是通过专用MapSerializer,但该序列器会检查其 key/value 类型的注解——而Object.class是所有类型的公共基类,覆盖最广。 -
过滤器名必须严格一致:
@JsonFilter("filter")中的"filter"必须与SimpleFilterProvider.addFilter("filter", ...)中的第一个参数完全匹配。 -
线程安全性:
ObjectMapper实例应复用(它是线程安全的),但FilterProvider是有状态的;若需并发生成不同过滤规则的 JSON,建议为每次调用创建独立ObjectMapper实例,或使用objectMapper.copy().setFilterProvider(...)避免状态污染。 -
性能提示:相比手动构造新
Map再序列化,此方案在大数据量下更高效——避免了内存拷贝,且由 Jackson 原生 C++/Java 底层优化处理。
✅ 扩展:多场景快速切换示例
public String toJsonWithKeys(Map<string string> data, String... keepKeys) {
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Object.class, DynamicMixIn.class);
FilterProvider filter = new SimpleFilterProvider().addFilter(
"filter",
SimpleBeanPropertyFilter.filterOutAllExcept(Arrays.asList(keepKeys))
);
mapper.setFilterProvider(filter);
return mapper.writeValueAsString(data);
}
// 调用示例
String onlyKey1 = toJsonWithKeys(hashtable, "KEY1"); // {"KEY1":"VALUE1"}
String exceptKey2 = toJsonWithKeys(hashtable, "KEY1", "KEY3"); // {"KEY1":"VALUE1","KEY3":"VALUE3"}</string>
通过 Mix-in + FilterProvider 组合,你可在一个 HashMap 上按需生成任意过滤策略的 JSON,兼顾灵活性、性能与代码简洁性。











