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

如何配置Jackson反序列化时跳过含"deleted":"true"的JSON数组元素?

解决Jackson反序列化时过滤特定条目的问题

刚好之前做过类似的需求,Jackson有几种实用的方式可以实现过滤掉"deleted":"true"条目的效果,我给你分享两个最常用的方案,都是亲测有效的:

方案一:自定义List类型的反序列化器

这个方案直接针对List的反序列化过程,逐个检查元素并过滤,逻辑直观易懂。

步骤1:定义你的实体类

首先是对应JSON结构的Item类:

public class Item {
    private String id;
    private String deleted;

    // 生成getter、setter方法,以及必要的构造函数
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getDeleted() { return deleted; }
    public void setDeleted(String deleted) { this.deleted = deleted; }
}

步骤2:编写自定义反序列化器

创建一个继承JsonDeserializer的类,专门处理List<Item>的反序列化:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class FilteredItemListDeserializer extends JsonDeserializer<List<Item>> {

    @Override
    public List<Item> deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        ObjectMapper mapper = (ObjectMapper) parser.getCodec();
        JsonNode rootNode = mapper.readTree(parser);
        List<Item> filteredItems = new ArrayList<>();

        // 遍历JSON数组中的每个元素
        if (rootNode.isArray()) {
            Iterator<JsonNode> elementIterator = rootNode.elements();
            while (elementIterator.hasNext()) {
                JsonNode itemNode = elementIterator.next();
                // 注意:你的deleted字段是字符串类型的"true"/"false",所以要用字符串比较
                if (!"true".equals(itemNode.get("deleted").asText())) {
                    // 将符合条件的节点转换为Item对象并加入列表
                    Item item = mapper.treeToValue(itemNode, Item.class);
                    filteredItems.add(item);
                }
            }
        }
        return filteredItems;
    }
}

步骤3:注册反序列化器并使用

在ObjectMapper中注册这个自定义反序列化器,然后就可以正常反序列化了:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.core.type.TypeReference;

public class Main {
    public static void main(String[] args) throws IOException {
        String jsonData = "[{\"id\": \"abc\", \"deleted\": \"true\"},{\"id\": \"def\", \"deleted\": \"false\"}]";

        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        // 为List<Item>类型注册自定义反序列化器
        module.addDeserializer(new TypeReference<List<Item>>() {}, new FilteredItemListDeserializer());
        mapper.registerModule(module);

        List<Item> result = mapper.readValue(jsonData, new TypeReference<List<Item>>() {});
        // 此时result中只会包含id为def的Item对象
    }
}

方案二:通过BeanDeserializerModifier拦截单个对象反序列化

这个方案更灵活,它会拦截所有Item对象的反序列化过程,如果是标记为deleted的对象就返回null,再配置Jackson自动忽略集合中的null元素,适合Item可能出现在其他集合或嵌套结构中的场景。

步骤1:编写BeanDeserializerModifier

创建一个修改器类,用来替换默认的Item反序列化器:

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;

import java.io.IOException;

public class ItemDeserializerModifier extends BeanDeserializerModifier {

    @Override
    public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
        // 只处理Item类的反序列化
        if (beanDesc.getBeanClass() == Item.class) {
            return new StdDeserializer<Item>(Item.class) {
                @Override
                public Item deserialize(JsonParser parser, DeserializationContext context) throws IOException {
                    JsonNode itemNode = parser.getCodec().readTree(parser);
                    // 检查deleted字段,返回null表示过滤该对象
                    if ("true".equals(itemNode.get("deleted").asText())) {
                        return null;
                    }
                    // 否则使用默认的反序列化逻辑
                    return ((StdDeserializer<?>) deserializer).deserialize(parser, context);
                }
            };
        }
        return super.modifyDeserializer(config, beanDesc, deserializer);
    }
}

步骤2:配置ObjectMapper并使用

注册修改器,同时配置Jackson忽略集合中的null元素:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.core.type.TypeReference;

public class Main {
    public static void main(String[] args) throws IOException {
        String jsonData = "[{\"id\": \"abc\", \"deleted\": \"true\"},{\"id\": \"def\", \"deleted\": \"false\"}]";

        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.setDeserializerModifier(new ItemDeserializerModifier());
        mapper.registerModule(module);

        // 配置Jackson忽略集合中的null元素
        mapper.configure(DeserializationFeature.ACCEPT_NULL_ARRAY_ELEMENTS, false);

        List<Item> result = mapper.readValue(jsonData, new TypeReference<List<Item>>() {});
        // 同样得到只包含id为def的Item列表
    }
}

关键注意点

一定要注意你的deleted字段是字符串类型的"true",不是布尔值true,所以判断的时候必须用字符串相等比较,不能用itemNode.get("deleted").asBoolean(),否则会出现判断错误的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:33:00