无POJO场景下,如何动态将JSON转换为带自定义命名空间的XML?
实现方法
由于没有对应POJO,我们可以基于Jackson的树模型(JsonNode)结合XmlMapper的命名空间配置来实现需求,核心分为字段名映射和命名空间配置两步:
1. 修改JSON节点字段名(Status → state)
目标XML需要<ns2:state>而非原JSON的Status字段,先通过树模型手动调整字段名:
// 读取原始JSON为JsonNode JsonNode originalNode = objectMapper.readTree(jsonString); // 创建新节点存储修改后的结构 ObjectNode modifiedNode = objectMapper.createObjectNode(); // 将原"Status"字段的值转移到"state"字段下 modifiedNode.set("state", originalNode.get("Status"));
2. 配置XmlMapper的命名空间
给XmlMapper设置命名空间URI、前缀映射,确保根节点和子元素都带上指定命名空间:
// 初始化XmlMapper并配置命名空间 XmlMapper xmlMapper = new XmlMapper(); // 设置默认命名空间URI xmlMapper.setDefaultNamespace("http://whatever-it-is.de/"); // 绑定前缀"ns2"到目标命名空间 xmlMapper.getFactory().setXMLNamespacePrefixes(Map.of("ns2", "http://whatever-it-is.de/"));
完整代码示例
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 javax.xml.namespace.QName; import java.util.Map; public class JsonToXmlWithNamespace { public static void main(String[] args) throws Exception { String jsonString = "{\"Status\": \"OK\"}"; final ObjectMapper objectMapper = new ObjectMapper(); // 调整字段名 JsonNode originalNode = objectMapper.readTree(jsonString); ObjectNode modifiedNode = objectMapper.createObjectNode(); modifiedNode.set("state", originalNode.get("Status")); // 配置XmlMapper命名空间 XmlMapper xmlMapper = new XmlMapper(); xmlMapper.setDefaultNamespace("http://whatever-it-is.de/"); xmlMapper.getFactory().setXMLNamespacePrefixes(Map.of("ns2", "http://whatever-it-is.de/")); // 序列化生成带命名空间的XML String xmlString = xmlMapper .writerWithDefaultPrettyPrinter() // 用QName指定根节点的命名空间、名称和前缀 .withRootName(new QName("http://whatever-it-is.de/", "rootname", "ns2")) .writeValueAsString(modifiedNode); System.out.println(xmlString); } }
输出结果
运行后会生成符合要求的XML:
<ns2:rootname xmlns:ns2="http://whatever-it-is.de/"> <ns2:state>OK</ns2:state> </ns2:rootname>
关键说明
- 通过
QName明确指定根节点的命名空间信息,确保根节点带上ns2前缀和命名空间声明。 setDefaultNamespace让所有子元素自动继承命名空间,配合前缀映射,子元素会自动带上ns2前缀。- 字段名修改通过树模型直接调整,无需依赖POJO的注解配置。
内容的提问来源于stack exchange,提问作者dank
相关产品推荐
相关产品推荐

