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

Java中解析键不固定的JSON遇阻,如何用mapper.readValue()处理?

处理Java中动态键的JSON解析问题

嘿,这个场景我太熟悉了——当JSON里的键是动态不固定的时候,确实没法直接用预定义的POJO配合mapper.readValue()来解析。不过Jackson库本身提供了好几种灵活的解决方案,我给你分享几个最常用的:

方案1:用Map<String, List<String>>直接接收

因为你的JSON结构是字符串键对应字符串列表,直接用泛型Map就能完美匹配。这里要注意用TypeReference来指定泛型类型,避免Jackson把列表解析成非预期的类型:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.util.Map;

public class JsonParser {
    public static void main(String[] args) throws Exception {
        String json = "{ \"-5\": [ \"15:D1_CHANNEL_ID_SK\", \"23:D1_CALL_BEGIN_DATE\", \"87:D1_CELL_ID\" ], \"-4\": [ \"31:I_RECHARGE_AMOUNT\", \"59:I_INBUNDLED_UNIT\", \"60:I_DAY_NIGHT_FLAG\", \"53:PD_UPSELL_PACK_ID\", \"146:AON\" ] }";
        
        ObjectMapper mapper = new ObjectMapper();
        // 用TypeReference明确泛型类型
        Map<String, List<String>> dynamicMap = mapper.readValue(json, new TypeReference<Map<String, List<String>>>() {});
        
        // 遍历处理每个键值对
        for (Map.Entry<String, List<String>> entry : dynamicMap.entrySet()) {
            String key = entry.getKey();
            List<String> values = entry.getValue();
            System.out.printf("键:%s,对应的值列表:%s%n", key, values);
        }
    }
}

方案2:用JsonNode灵活遍历解析

如果不需要把整个JSON转成Java对象,只是需要读取或处理特定内容,JsonNode会更灵活,它相当于JSON的树形结构表示:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class JsonNodeParser {
    public static void main(String[] args) throws Exception {
        String json = "{ \"-5\": [ \"15:D1_CHANNEL_ID_SK\", \"23:D1_CALL_BEGIN_DATE\", \"87:D1_CELL_ID\" ], \"-4\": [ \"31:I_RECHARGE_AMOUNT\", \"59:I_INBUNDLED_UNIT\", \"60:I_DAY_NIGHT_FLAG\", \"53:PD_UPSELL_PACK_ID\", \"146:AON\" ] }";
        
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(json);
        
        // 遍历所有动态键
        Iterator<String> fieldNames = rootNode.fieldNames();
        while (fieldNames.hasNext()) {
            String key = fieldNames.next();
            JsonNode valueNode = rootNode.get(key);
            
            // 确保值是数组类型,再转成列表
            if (valueNode.isArray()) {
                List<String> values = new ArrayList<>();
                for (JsonNode item : valueNode) {
                    values.add(item.asText());
                }
                System.out.printf("键:%s,对应的值列表:%s%n", key, values);
            }
        }
    }
}

方案3:结合@JsonAnySetter注解封装成实体类

如果你的JSON除了这些动态键,还有其他固定字段,或者想把动态键的逻辑封装到实体类里,可以用@JsonAnySetter注解来统一处理动态键:

import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DynamicData {
    // 用Map存储所有动态键值对
    private Map<String, List<String>> dynamicFields = new HashMap<>();

    // 注解标记:所有未匹配到固定字段的键都会调用这个方法
    @JsonAnySetter
    public void setDynamicField(String key, List<String> value) {
        dynamicFields.put(key, value);
    }

    public Map<String, List<String>> getDynamicFields() {
        return dynamicFields;
    }

    public static void main(String[] args) throws Exception {
        String json = "{ \"-5\": [ \"15:D1_CHANNEL_ID_SK\", \"23:D1_CALL_BEGIN_DATE\", \"87:D1_CELL_ID\" ], \"-4\": [ \"31:I_RECHARGE_AMOUNT\", \"59:I_INBUNDLED_UNIT\", \"60:I_DAY_NIGHT_FLAG\", \"53:PD_UPSELL_PACK_ID\", \"146:AON\" ] }";
        
        ObjectMapper mapper = new ObjectMapper();
        DynamicData data = mapper.readValue(json, DynamicData.class);
        
        // 从实体类中获取动态字段
        Map<String, List<String>> fields = data.getDynamicFields();
        fields.forEach((key, values) -> System.out.printf("键:%s,对应的值列表:%s%n", key, values));
    }
}

小提示

  • 确保你已经引入了Jackson的核心依赖(比如jackson-databind),如果用Maven的话,在pom.xml里添加对应的依赖即可。
  • 这些方案都能完美处理你给出的JSON结构,你可以根据自己的业务场景选择最适合的一种。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:25:27