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

Java按指定section替换JSON变量后反序列化为POJO的注解实现咨询

结论

无法仅通过Java JSON库的常规基础注解直接实现该需求,你需要结合自定义反序列化逻辑完成,以业界最常用的Jackson库为例,可以通过「自定义反序列化器+注解」的形式实现你要的效果,具体思路如下:

实现方案

  • 第一步:先定义原始JSON对应的基础POJO结构,包含common、section1、section2三个节点的对应字段,也可以用Map<String, Section>类型存储所有业务分段,方便后续扩展更多section。
  • 第二步:自定义反序列化注解,比如命名为@SectionAware,用于标注需要输出最终合并后data结果的字段,同时支持传入section参数。
  • 第三步:实现对应自定义反序列化器,核心逻辑如下:
    1. 读取完整JSON树,根据传入的section参数获取对应分段的variables变量映射表、以及data字段存储的ref列表
    2. 提取common块下的所有data条目,筛选出ref值在上述ref列表中的条目
    3. 遍历筛选后条目的所有字段值,匹配${变量名}格式的占位符,从variables映射表中取出对应实际值完成替换,移除不需要的ref字段后即可得到你要的最终data结构
  • 如果业务规则后续可能频繁调整,更推荐你先把JSON直接反序列化为原始结构POJO,单独写一个工具类做占位符替换、字段合并的逻辑,这种方式可读性和可维护性比自定义反序列化器更高。

核心代码示例

// 自定义注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonDeserialize(using = SectionDataDeserializer.class)
public @interface SectionAware {
    String section() default "";
}

// 自定义反序列化器核心逻辑
public class SectionDataDeserializer extends StdDeserializer<List<Map<String, Object>>> {
    @Override
    public List<Map<String, Object>> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode root = p.readValueAsTree();
        // 可通过注解属性、ThreadLocal或者Jackson的注入机制获取传入的section参数
        String section = ctxt.findInjectableValue("targetSection", null, null).toString();
        JsonNode sectionNode = root.get(section);
        // 读取变量映射表
        Map<String, String> variables = ctxt.readValue(sectionNode.get("variables").traverse(p.getCodec()), new TypeReference<Map<String, String>>() {});
        // 读取需要引用的ref列表
        List<String> refList = ctxt.readValue(sectionNode.get("data").traverse(p.getCodec()), new TypeReference<List<String>>() {});
        // 处理common数据并替换占位符
        List<Map<String, Object>> result = new ArrayList<>();
        for (JsonNode commonDataItem : root.get("common").get("data")) {
            String ref = commonDataItem.get("ref").asText();
            if (!refList.contains(ref)) continue;
            Map<String, Object> item = ctxt.readValue(commonDataItem.traverse(p.getCodec()), new TypeReference<Map<String, Object>>() {});
            item.remove("ref");
            // 占位符替换逻辑
            item.replaceAll((key, value) -> {
                String valStr = value.toString();
                if (valStr.startsWith("${") && valStr.endsWith("}")) {
                    return variables.getOrDefault(valStr, valStr);
                }
                return value;
            });
            result.add(item);
        }
        return result;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:36:07