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

Apache Camel Java实现JSON数组按唯一ID分组的格式转换方案

按ID分组处理JSON的Java实现方案

需求说明

我有如下JSON输入请求,需要按ID参数进行分组处理:

输入示例

[
    {
        "ID": "1234",
        "CustomerName": "KUMAR",
        "BranchName": "HARBOUR",
        "SchemeName": "GOLD",
        "MobileNumber": "123456789",
        "CustomerType": "PRIMARY",
        "DedupeFound" : "NO"
    },
    {
        "ID": "1234",
        "CustomerName": "SEAN",
        "BranchName": "HARBOUR",
        "SchemeName": "GOLD",
        "MobileNumber": "123456789",
        "CustomerType": "SECONDARY",
        "DedupeFound" : "YES"
    },
    {
        "ID": "5678",
        "CustomerName": "MARK",
        "BranchName": "CANTONMENT",
        "SchemeName": "DIAMOND",
        "MobileNumber": "123456789",
        "CustomerType": "PRIMARY",
        "DedupeFound" : "NO"
    },
    {
        "ID": "5678",
        "CustomerName": "STEVE",
        "BranchName": "CANTONMENT",
        "SchemeName": "DIAMOND",
        "MobileNumber": "123456789",
        "CustomerType": "SECONDARY",
        "DedupeFound" : "YES"
    }
]

转换规则

  • 首先按ID字段分组,每组外层仅展示CustomerType为PRIMARY的主客户的基础字段信息
  • 每个ID对应记录内新增DedupeDetails数组,存放该ID下所有客户的去重相关字段信息

期望输出示例

[
    {
        "ID": "1234",
        "CustomerName": "KUMAR",
        "BranchName": "HARBOUR",
        "SchemeName": "GOLD",
        "MobileNumber": "123456789",
        "DedupeDetails": [
            {
                "CustomerType": "PRIMARY",
                "CustomerName": "KUMAR",
                "DedupeFound" : "NO"
            },
            {
                "CustomerType": "SECONDARY",
                "CustomerName": "SEAN",
                "DedupeFound" : "YES"
            }
        ]
    },
    {
        "ID": "5678",
        "CustomerName": "MARK",
        "BranchName": "CANTONMENT",
        "SchemeName": "DIAMOND",
        "MobileNumber": "123456789",
        "DedupeDetails": [
            {
                "CustomerType": "PRIMARY",
                "CustomerName": "MARK",
                "DedupeFound" : "NO"
            },
            {
                "CustomerType": "SECONDARY",
                "CustomerName": "STEVE",
                "DedupeFound" : "YES"
            }
        ]
    }
]

现有代码问题

已经在Apache Camel中编写Java代码,成功将JSON字符串映射为对象列表,但不知道如何实现分组逻辑得到上述输出。现有代码如下:

package com.mycompany.Login;

import java.util.List;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.sql.Timestamp;
import java.io.File;
import java.io.PrintWriter;
import java.sql.Time;
import com.mycompany.Login.*;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mycompany.Dedupe.DedupeRoot.DedupeRes;

public class LoginMapping implements Processor{
    public void process(Exchange ex)throws Exception{ 
        try {   
            String responseString = {Input mentioned in post};          
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);         
            List<DedupeRes> dedupe = Arrays.asList(mapper.readValue(responseString, DedupeRes[].class));  
            int total = dedupe.size();          
            if (total > 0)
            {               
                for (int i = 0; i < total; i++) {                   
                    
                }               
            }
            ex.getIn().setBody(responseString);
        }       
        catch(Exception e) {
            ex.getIn().setHeader("ExpMsg", "Undefined");
            throw e;
        }   
    }
}

实现方案

第一步:新增输出对应的实体类

首先创建两个新类,分别对应输出的外层结构和DedupeDetails的结构:

// 去重详情实体类
public class DedupeDetail {
    private String CustomerType;
    private String CustomerName;
    private String DedupeFound;
    // 补全getter、setter、无参构造方法
}

// 输出结果外层实体类
public class DedupeOutput {
    private String ID;
    private String CustomerName;
    private String BranchName;
    private String SchemeName;
    private String MobileNumber;
    private List<DedupeDetail> DedupeDetails;
    // 补全getter、setter、无参构造方法
}

第二步:修改Processor的处理逻辑

替换process方法内的遍历部分,实现分组转换:

public void process(Exchange ex)throws Exception{ 
    try {   
        String responseString = ex.getIn().getBody(String.class); // 从Camel交换体取输入JSON,不要硬编码      
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);         
        List<DedupeRes> dedupeList = Arrays.asList(mapper.readValue(responseString, DedupeRes[].class));  

        // 1. 按ID分组
        HashMap<String, List<DedupeRes>> idGroupMap = new HashMap<>();
        for (DedupeRes res : dedupeList) {
            idGroupMap.computeIfAbsent(res.getID(), k -> new ArrayList<>()).add(res);
        }

        // 2. 处理每个分组生成输出
        List<DedupeOutput> outputList = new ArrayList<>();
        for (String id : idGroupMap.keySet()) {
            List<DedupeRes> groupItems = idGroupMap.get(id);
            DedupeOutput output = new DedupeOutput();
            List<DedupeDetail> details = new ArrayList<>();

            for (DedupeRes item : groupItems) {
                // 填充去重详情
                DedupeDetail detail = new DedupeDetail();
                detail.setCustomerType(item.getCustomerType());
                detail.setCustomerName(item.getCustomerName());
                detail.setDedupeFound(item.getDedupeFound());
                details.add(detail);

                // 找到主客户填充外层字段
                if ("PRIMARY".equals(item.getCustomerType())) {
                    output.setID(item.getID());
                    output.setCustomerName(item.getCustomerName());
                    output.setBranchName(item.getBranchName());
                    output.setSchemeName(item.getSchemeName());
                    output.setMobileNumber(item.getMobileNumber());
                }
            }
            output.setDedupeDetails(details);
            outputList.add(output);
        }

        // 把输出列表转成JSON字符串放回交换体
        String outputJson = mapper.writeValueAsString(outputList);
        ex.getIn().setBody(outputJson);
    }       
    catch(Exception e) {
        ex.getIn().setHeader("ExpMsg", "Undefined");
        throw e;
    }   
}

注意事项

  • 确保你的DedupeRes实体类已经包含所有输入字段对应的getter方法,否则取值会报错
  • 如果你的Java版本支持Stream API,也可以用Collectors.groupingBy替代HashMap手动分组,代码会更简洁
  • 你提供的期望输出示例里部分字段末尾漏了逗号,实际转换时Jackson会自动处理格式问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:36:02