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

SpringBoot中如何移除JSON的nameValuePairs键并添加event键?

问题描述

现有XML转CitiMarketSSAEvent对象的方法:

public CitiMarketSSAEvent convertXmlToObject(String xml){
    CitiMarketSSAEvent citiMarket = null;
    
    JAXBContext jaxbContext = JAXBContext.newInstance(CitiMarketSSAEvent.class);
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    StringReader reader = new StringReader(xml);
    citiMarket = (CitiMarketSSAEvent) unmarshaller.unmarshal(reader);
    return citiMarket;
}

以及原始的对象转JSON方法:

public String convertObjectToJson(CitiMarketSSAEvent citiMarketObject) {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.setPrettyPrinting();
    gsonBuilder.disableHtmlEscaping();

    Gson gson = gsonBuilder.create();
    return gson.toJson(citiMarketObject, CitiMarketSSAEvent.class);
}

转换后JSON结构如下:

{
    "header":{
        "name": "transactionCount",
        "version": "2.0",
        "code": "1530",
        "country": "MX",
        "domain": "counts",
        "time": "2018-10-11 11:20:34.323 GMT"
    },
    "body":{
        "INPUNT": "I",
        "MESSAGE_01": "RSTW",
        "MESSAGE_02": "MNXTYP",
        "MESSAGE_03": "RSTWERDCV",
        "SEND_TIME": "20-NOV-2011 04:53:04 p.m.",
        "RCV_ID": "ABGRCV",
        "FORMAT0_MONTO": "200,000,300.00",
        "FORMATO_MONEDA": "USD",
        "CONTROL_01": "MSG1RCVSND",
        "CONTROL_02": "MSG2RCVSND",
        "CONTROL_03": "MSG3RCVSND"
    }
}

需求是给JSON添加顶层event键,使结构变为:

{
 "event":{
    "header":{
        "name": "transactionCount",
        "version": "2.0",
        "code": "1530",
        "country": "MX",
        "domain": "counts",
        "time": "2018-10-11 11:20:34.323 GMT"
    },
    "body":{
        "INPUNT": "I",
        "MESSAGE_01": "RSTW",
        "MESSAGE_02": "MNXTYP",
        "MESSAGE_03": "RSTWERDCV",
        "SEND_TIME": "20-NOV-2011 04:53:04 p.m.",
        "RCV_ID": "ABGRCV",
        "FORMAT0_MONTO": "200,000,300.00",
        "FORMATO_MONEDA": "USD",
        "CONTROL_01": "MSG1RCVSND",
        "CONTROL_02": "MSG2RCVSND",
        "CONTROL_03": "MSG3RCVSND"
    }
  }
}

改用JSONObject修改转换方法后:

public String convertObjectToJson(CitiMarketSSAEvent citiMarketObject) {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setPrettyPrinting();
        gsonBuilder.disableHtmlEscaping();
        
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("event",citiMarketObject);
        
        Gson gson = gsonBuilder.create();
        return gson.toJson(jsonObj, JSONObject.class);                                            
}

生成的JSON多出了nameValuePairs键:

{
    "nameValuePairs":{
        "event":{
            "header":{
                "name": "transactionCount",
                "version": "2.0",
                "code": "1530",
                "country": "MX",
                "domain": "counts",
                "time": "2018-10-11 11:20:34.323 GMT"
            },
            "body":{
                "INPUNT": "I",
                "MESSAGE_01": "RSTW",
                "MESSAGE_02": "MNXTYP",
                "MESSAGE_03": "RSTWERDCV",
                "SEND_TIME": "20-NOV-2011 04:53:04 p.m.",
                "RCV_ID": "ABGRCV",
                "FORMAT0_MONTO": "200,000,300.00",
                "FORMATO_MONEDA": "USD",
                "CONTROL_01": "MSG1RCVSND",
                "CONTROL_02": "MSG2RCVSND",
                "CONTROL_03": "MSG3RCVSND"
            }
        }
    }
}
解决方案

原因说明

你使用的JSONObject属于org.json包,该类内部通过nameValuePairs成员变量存储所有键值对,Gson序列化时会直接输出这个成员字段,因此多出了一层无用的nameValuePairs结构。以下是几种可行的解决方法:


方法1:用Map作为外层容器(简单快捷)

用HashMap代替JSONObject作为外层包装,Gson可以直接将Map序列化为键值对结构,不会生成额外字段:

public String convertObjectToJson(CitiMarketSSAEvent citiMarketObject) {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.setPrettyPrinting();
    gsonBuilder.disableHtmlEscaping();
    
    Map<String, Object> wrapperMap = new HashMap<>();
    wrapperMap.put("event", citiMarketObject);
    
    Gson gson = gsonBuilder.create();
    return gson.toJson(wrapperMap);
}

方法2:创建专用包装类(类型安全,推荐长期使用)

定义一个专门的包装类来承载event字段,类型更安全,也便于后续扩展:

// 包装类定义
public class EventWrapper {
    private CitiMarketSSAEvent event;

    // 无参构造(Gson序列化需要)
    public EventWrapper() {}

    // 带参构造
    public EventWrapper(CitiMarketSSAEvent event) {
        this.event = event;
    }

    // Getter方法
    public CitiMarketSSAEvent getEvent() {
        return event;
    }

    // Setter方法
    public void setEvent(CitiMarketSSAEvent event) {
        this.event = event;
    }
}

// 修改后的转换方法
public String convertObjectToJson(CitiMarketSSAEvent citiMarketObject) {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.setPrettyPrinting();
    gsonBuilder.disableHtmlEscaping();
    
    EventWrapper wrapper = new EventWrapper(citiMarketObject);
    
    Gson gson = gsonBuilder.create();
    return gson.toJson(wrapper);
}

方法3:先序列化对象再包装(兼容原JSONObject用法,效率稍低)

如果一定要保留JSONObject的使用,可以先将对象序列化为JSON字符串,再包装到外层JSONObject中,最后用JSONObject自身的方法输出格式化JSON:

public String convertObjectToJson(CitiMarketSSAEvent citiMarketObject) {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.setPrettyPrinting();
    gsonBuilder.disableHtmlEscaping();
    
    Gson gson = gsonBuilder.create();
    // 先将对象转为JSON字符串
    String eventJsonStr = gson.toJson(citiMarketObject);
    
    JSONObject outerJson = new JSONObject();
    // 将字符串转为JSONObject后放入外层
    outerJson.put("event", new JSONObject(eventJsonStr));
    
    // 输出格式化后的JSON,参数4代表缩进4个空格
    return outerJson.toString(4);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:35:22