开发的项目需要「一套数据,两种格式」:对外同时提供 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");
}
}
```