You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jackson过滤HashMap指定键并转换为JSON?

问题原因

你之前的代码无效,是因为Jackson的SimpleBeanPropertyFilter是为JavaBean的字段过滤设计的,而非Map的键。直接给ObjectMapper设置FilterProvider对Map类型的序列化完全不起作用。

Jackson实现Map键动态过滤的方案

下面是几种Jackson原生的高效实现方式,能满足你基于同一Map生成多份不同过滤规则JSON的需求:

方案1:自定义序列化修改器+ObjectWriter(推荐)

通过自定义BeanSerializerModifier拦截Map的序列化过程,动态控制哪些键需要保留。每次需要不同过滤规则时,生成对应的ObjectWriter即可,无需修改原ObjectMapper。

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.fasterxml.jackson.databind.ser.std.MapSerializer;

import java.io.IOException;
import java.util.Map;
import java.util.Set;

public class MapKeyFilterModifier extends BeanSerializerModifier {
    private final Set<String> allowedKeys;

    public MapKeyFilterModifier(Set<String> allowedKeys) {
        this.allowedKeys = allowedKeys;
    }

    @Override
    public JsonSerializer<?> modifyMapSerializer(SerializationConfig config, MapType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer) {
        return new FilteredMapSerializer((MapSerializer) serializer, allowedKeys);
    }

    private static class FilteredMapSerializer extends MapSerializer {
        private final Set<String> allowedKeys;

        public FilteredMapSerializer(MapSerializer src, Set<String> allowedKeys) {
            super(src);
            this.allowedKeys = allowedKeys;
        }

        @Override
        public void serialize(Map<?, ?> value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            gen.writeStartObject();
            for (Map.Entry<?, ?> entry : value.entrySet()) {
                String key = entry.getKey().toString();
                if (allowedKeys.contains(key)) {
                    gen.writeFieldName(key);
                    provider.defaultSerializeValue(entry.getValue(), gen);
                }
            }
            gen.writeEndObject();
        }
    }
}

使用方式

// 初始化原Map
Map<String, String> hashMap = new HashMap<>();
hashMap.put("KEY1", "VALUE1");
hashMap.put("KEY2", "VALUE2");
hashMap.put("KEY3", "VALUE3");

ObjectMapper objectMapper = new ObjectMapper();

// 生成仅保留KEY1的JSON
Set<String> filter1 = Set.of("KEY1");
ObjectWriter writer1 = objectMapper.writer()
        .with(new BeanSerializerModifier[]{new MapKeyFilterModifier(filter1)});
System.err.println(writer1.writeValueAsString(hashMap)); // 输出 {"KEY1":"VALUE1"}

// 生成保留KEY2、KEY3的JSON
Set<String> filter2 = Set.of("KEY2", "KEY3");
ObjectWriter writer2 = objectMapper.writer()
        .with(new BeanSerializerModifier[]{new MapKeyFilterModifier(filter2)});
System.err.println(writer2.writeValueAsString(hashMap)); // 输出 {"KEY2":"VALUE2","KEY3":"VALUE3"}

方案2:流式过滤Map(简单高效)

如果不需要严格依赖Jackson的序列化过滤机制,这种方式更直接,性能也更优:

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

// 初始化原Map
Map<String, String> hashMap = new HashMap<>();
hashMap.put("KEY1", "VALUE1");
hashMap.put("KEY2", "VALUE2");
hashMap.put("KEY3", "VALUE3");

ObjectMapper objectMapper = new ObjectMapper();

// 过滤规则1:保留KEY1
Set<String> allowed1 = Set.of("KEY1");
Map<String, String> filteredMap1 = hashMap.entrySet().stream()
        .filter(entry -> allowed1.contains(entry.getKey()))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.err.println(objectMapper.writeValueAsString(filteredMap1));

// 过滤规则2:保留KEY2、KEY3
Set<String> allowed2 = Set.of("KEY2", "KEY3");
Map<String, String> filteredMap2 = hashMap.entrySet().stream()
        .filter(entry -> allowed2.contains(entry.getKey()))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.err.println(objectMapper.writeValueAsString(filteredMap2));
总结

如果坚持使用Jackson的序列化过滤机制,方案1是最优选择——它可以基于同一Map生成任意过滤规则的JSON,且无需修改原Map数据;如果追求实现简单,方案2的流式过滤更直接高效。

内容的提问来源于stack exchange,提问作者randomgood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 03:21:00