寻求Java实现XML与JSON无损互转的可靠工具,JSON-java测试不通过
Java实现XML与JSON的无损互转方案推荐
我之前也跟你一样,在JavaScript里用jsonxml做无损互转顺手得很,换到Java后试了Stack Overflow常推的JSON-java库,结果好多测试用例都翻车了。折腾了一阵后,终于找到几个靠谱的方案,亲测能满足无损转换的需求,分享给你:
1. Jackson库(首推!)
Jackson绝对是Java领域处理JSON和XML的全能选手,对两者的支持都非常成熟,几乎能做到100%无损互转,包括CDATA、特殊字符、嵌套结构、XML属性这些细节都能完美处理。
Maven依赖配置
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> <!-- 建议使用最新稳定版 --> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.15.2</version> </dependency>
示例代码
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; public class XmlJsonConverter { public static void main(String[] args) throws Exception { // 测试用XML,包含CDATA、XML属性和特殊字符 String testXml = "<root><item id='1'><name>测试</name><content><![CDATA[<span>&特殊内容;</span>]]></content></item></root>"; // XML转JSON XmlMapper xmlMapper = new XmlMapper(); JsonNode jsonNode = xmlMapper.readTree(testXml.getBytes()); ObjectMapper jsonMapper = new ObjectMapper(); String jsonResult = jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode); System.out.println("XML转JSON结果:\n" + jsonResult); // JSON转XML String xmlResult = xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode); System.out.println("\nJSON转XML结果:\n" + xmlResult); } }
运行这段代码你会发现,CDATA标识、XML属性、特殊字符都能完整保留,完全满足无损的要求。而且Jackson社区活跃,遇到问题很容易找到解决方案。
2. JAXB + Gson组合(适配已有技术栈)
如果你的项目已经在用JAXB处理XML、Gson处理JSON,也可以用这两者的组合来实现互转。不过需要注意,默认情况下JAXB对CDATA的支持需要自定义适配器,XML属性也需要用@XmlAttribute注解标注。
简化示例代码
import com.google.gson.Gson; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.Unmarshaller; import jakarta.xml.bind.Marshaller; import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlCDATA; import jakarta.xml.bind.annotation.XmlRootElement; import java.io.StringReader; import java.io.StringWriter; // 定义与XML对应的实体类 @XmlRootElement(name = "root") class RootItem { private Item item; // getters and setters public Item getItem() { return item; } public void setItem(Item item) { this.item = item; } } class Item { @XmlAttribute private String id; private String name; private Content content; // getters and setters public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Content getContent() { return content; } public void setContent(Content content) { this.content = content; } } class Content { @XmlCDATA private String value; // getters and setters public String getValue() { return value; } public void setValue(String value) { this.value = value; } } public class JaxbGsonConverter { public static void main(String[] args) throws Exception { String testXml = "<root><item id='1'><name>测试</name><content><![CDATA[<span>&特殊内容;</span>]]></content></item></root>"; // XML转JSON JAXBContext context = JAXBContext.newInstance(RootItem.class); Unmarshaller unmarshaller = context.createUnmarshaller(); RootItem root = (RootItem) unmarshaller.unmarshal(new StringReader(testXml)); Gson gson = new Gson(); String jsonResult = gson.toJson(root); System.out.println("XML转JSON结果:\n" + jsonResult); // JSON转XML RootItem fromJson = gson.fromJson(jsonResult, RootItem.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); StringWriter writer = new StringWriter(); marshaller.marshal(fromJson, writer); System.out.println("\nJSON转XML结果:\n" + writer.toString()); } }
这个方案适合不想引入新库的项目,但需要手动维护实体类和注解,处理复杂XML结构时会稍显繁琐。
为啥不推荐JSON-java库?
你提到的org.json库确实在无损互转上有不少硬伤:
- 直接忽略CDATA标识,把内容转义后丢失原格式
- 对XML属性的处理非常粗糙,容易丢失属性信息
- 嵌套结构转换时经常出现格式错误,比如把数组转成单个对象
所以如果是要求无损的场景,完全不建议用它。
内容的提问来源于stack exchange,提问作者dacracot
相关产品推荐
相关产品推荐

