JAVA :JSONObject转换为XML

开发的项目需要「一套数据,两种格式」:对外同时提供 JSON 接口和 XML 接口。那就需要将JSON对象转化为XML对象。

依赖

复制代码
<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.4</version>
</dependency>
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.51</version>
</dependency>

完整工具类,支持 JSONObject、嵌套对象、数组,输出完整xml文档:

复制代码
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.StringWriter;

public class Json2XmlUtil {

    /**
     * JSONObject转完整XML字符串
     * @param jsonObject json对象
     * @param rootName 根节点名称
     * @return xml完整字符串
     */
    public static String jsonToXml(JSONObject jsonObject, String rootName) {
        Document document = DocumentHelper.createDocument();
        // xml声明头 <?xml version="1.0" encoding="UTF-8"?>
        document.setXMLEncoding("UTF-8");
        Element root = document.addElement(rootName);
        parseJsonObject(jsonObject, root);

        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setIndent("  ");
        format.setNewlines(true);
        StringWriter writer = new StringWriter();
        try (XMLWriter xmlWriter = new XMLWriter(writer, format)) {
            xmlWriter.write(document);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return writer.toString();
    }

    /**
     * 递归解析JSONObject
     */
    private static void parseJsonObject(JSONObject jsonObj, Element parent) {
        for (String key : jsonObj.keySet()) {
            Object value = jsonObj.get(key);
            if (value instanceof JSONObject jo) {
                Element child = parent.addElement(key);
                parseJsonObject(jo, child);
            } else if (value instanceof JSONArray ja) {
                parseJsonArray(ja, parent, key);
            } else {
                // 普通文本值
                parent.addElement(key).setText(value == null ? "" : value.toString());
            }
        }
    }

    /**
     * 解析JSON数组
     */
    private static void parseJsonArray(JSONArray jsonArray, Element parent, String arrayKey) {
        for (int i = 0; i < jsonArray.size(); i++) {
            Object item = jsonArray.get(i);
            if (item instanceof JSONObject jo) {
                Element itemEle = parent.addElement(arrayKey);
                parseJsonObject(jo, itemEle);
            } else {
                parent.addElement(arrayKey).setText(item == null ? "" : item.toString());
            }
        }
    }

    // test
    public static void main(String[] args) {
        String json = "{\n" +
                "  \"userName\":\"李四\",\n" +
                "  \"hobby\":[\"篮球\",\"游泳\"],\n" +
                "  \"info\":{\"email\":\"test@xx.com\"}\n" +
                "}";
        JSONObject jsonObject = JSONObject.parseObject(json);
        String xmlResult = jsonToXml(jsonObject, "root");
        System.out.println(xmlResult);
    }
}

输出示例:

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <userName>李四</userName>
  <hobby>篮球</hobby>
  <hobby>游泳</hobby>
  <info>
    <email>test@xx.com</email>
  </info>
</root>

接口示例

复制代码
    @PostMapping(value = "/rest-xml/{path}/{version}", produces = MediaType.APPLICATION_ATOM_XML_VALUE)
    @Operation(summary = "RESTful XML调用", description = "外部系统调用RESTful XML接口")
    public String restXml(
            @Valid @PathVariable String path,
            @Valid @PathVariable String version,
            @RequestBody Object request) {
        // 根据path、version找到API
        // 根据API调用Service
        // 根据返回类型,输出XML
        return externalService.restXml(path, version, request);
    }

public String restXml(@Valid String path, @Valid String version, Object request) {
        log.info("外部系统调用 restXml 接口,name={}, version={}", path, version);

        // 用 restJson 的逻辑,返回JSON结果对象
        JSONObject result = new JSONObject();
        try {
            JSONObject data = restJson(path, version, request);
            if (data != null && data.containsKey("code") && data.getInteger("code") != 200) {
                result.put("status", data.getInteger("code"));
                result.put("message", data.getString("message"));
            } else {
                result.put("data", data);
                result.put("status", 200);
                result.put("message", "success");
            }
            return jsonToXmlUtils.jsonToXml(result, "response");
        } catch (Exception e) {
            log.error("JSON 转 XML 失败", e);
            result.put("status", 500);
            result.put("message", "JSON 转 XML 失败:" + e.getMessage());
            return jsonToXmlUtils.jsonToXml(result, "response");
        }
    }
    ```
相关推荐
fanruitian19 小时前
python 机器学习 交叉验证train_test_split 网格搜索GridSearchCV
开发语言·python·机器学习
鬼手点金20 小时前
Skills:领域能力的可组合单元
java·人工智能·笔记·自动化·1024程序员节
captain3761 天前
MyBatis(入门5)其他查询操作
java·数据库·spring boot·mybatis
Novproxy_Z1 天前
商用代理避坑:如何识别商家拿机房 IP 冒充住宅 IP
java·网络·tcp/ip
前端精髓1 天前
结构化输出with_structured_output(抽卡)
python·langchain
文丑颜不良啊1 天前
LeetCode1481~1500题目解析
java·leetcode
2601_962885721 天前
quotes 字段全解:涨跌幅、振幅、换手率的口径与单位
java·前端·spring
前端精髓1 天前
调用openrouter的免费API模型
java·前端·javascript
尹人入圣1 天前
目前热门的IP驱动产业新场景新工具
网络·python·网络协议·tcp/ip
步行cgn1 天前
Spring MVC 拦截器 Interceptor 详解:从执行流程到实战应用
java·spring·mvc