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

属性名为数字的JSON映射DTO及转XML的解决方案问询

可行解决方案有两种,均可满足你的需求:

方案1:基于org.json库实现递归重命名数字键(适配你现有代码栈)

你原有代码存在两个问题:

  1. 直接赋值newPayload = payload属于引用传递,两个变量指向同一个JSONObject实例,遍历过程中删除key会触发ConcurrentModificationException
  2. 未对value做类型判断和递归处理,所以只能处理顶层节点的数字键

修复后的完整实现如下,可递归处理所有层级的数字键:

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.XML;
import org.apache.commons.lang3.StringUtils;

public class NumericKeyProcessor {
    public static Object processNumericKeys(Object jsonNode) {
        // 处理JSON对象类型
        if (jsonNode instanceof JSONObject) {
            JSONObject originalObj = (JSONObject) jsonNode;
            JSONObject processedObj = new JSONObject();
            for (String key : originalObj.keySet()) {
                // 数字键增加前缀,避免XML标签非法
                String newKey = StringUtils.isNumber(key) ? "element" + key : key;
                // 递归处理当前键对应的值
                processedObj.put(newKey, processNumericKeys(originalObj.get(key)));
            }
            return processedObj;
        }
        // 处理JSON数组类型
        else if (jsonNode instanceof JSONArray) {
            JSONArray originalArr = (JSONArray) jsonNode;
            JSONArray processedArr = new JSONArray();
            for (int i = 0; i < originalArr.length(); i++) {
                processedArr.put(processNumericKeys(originalArr.get(i)));
            }
            return processedArr;
        }
        // 普通值类型直接返回
        else {
            return jsonNode;
        }
    }

    // 直接调用本方法即可完成JSON转XML
    public static String jsonToXml(String rawJson) {
        JSONObject originalJson = new JSONObject(rawJson);
        JSONObject processedJson = (JSONObject) processNumericKeys(originalJson);
        // 直接使用org.json自带工具转XML
        return XML.toString(processedJson);
    }
}

使用时直接调用NumericKeyProcessor.jsonToXml(你的原始JSON字符串)即可拿到符合规范的XML内容,完全不需要做DTO映射,绕开数字无法作为类属性名的问题。


方案2:基于Jackson实现(适配主流Spring栈项目)

如果你的项目已经依赖Jackson,可使用以下实现,不需要额外引入org.json依赖:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.commons.lang3.StringUtils;

public class JacksonJsonToXmlConverter {
    private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
    private static final XmlMapper XML_MAPPER = new XmlMapper();

    private static JsonNode processKeys(JsonNode node) {
        if (node.isObject()) {
            ObjectNode originalObj = (ObjectNode) node;
            ObjectNode processedObj = JSON_MAPPER.createObjectNode();
            originalObj.fields().forEachRemaining(entry -> {
                String newKey = StringUtils.isNumber(entry.getKey()) ? "element" + entry.getKey() : entry.getKey();
                processedObj.set(newKey, processKeys(entry.getValue()));
            });
            return processedObj;
        } else if (node.isArray()) {
            var processedArr = JSON_MAPPER.createArrayNode();
            node.forEach(item -> processedArr.add(processKeys(item)));
            return processedArr;
        }
        return node;
    }

    public static String convert(String rawJson) throws Exception {
        JsonNode root = JSON_MAPPER.readTree(rawJson);
        return XML_MAPPER.writeValueAsString(processKeys(root));
    }
}

注意事项

  • 键名前缀element可根据业务需要自行修改,只要符合XML标签命名规则即可
  • 两种方案均支持任意层级的嵌套JSON,不需要提前预知JSON结构
  • 不需要做DTO映射,直接完成JSON到XML的转换,适配你当前无时间重构的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 04:48:01