Object/XML Mapping (O/X Mapping)
前言
O/X Mapping 指 Java 对象与 XML 文档对象之间的转换,这是个古老的话题。可选的方案有:
- XMLBeans:目前主要作为 Apache POI 的模块,用于文档对象转换
- JAXB:选择 JAXB 在于作为语言特性,轻量级,结合性良好
- XStream:对命名空间支持较弱、默认对任何类都可以进行转换,较低版本存在安全漏洞,互联网业务慎用
- Castor:2004 年停止维护
- JiBX:最终版本 1.2.3,2011 年停止维护
最早 JSR31 发布 Jaxb1.0 版本,JSR 222 发布 Jaxb2.0,JDK1.6 并引入作为一部分。 最新版本 3.0 命名为 Jakarta XML Binding,作为 Jakarta EE 9 一部分。在JDK1.6/Jaxb 2.0 以下版本的环境中,使用过程中存在诸多问题。以下讨论仅限于 JDK6/Jaxb2.0 以上版本。
参考
- JAXB Release Notes
- x-stream
- JAXB转换对象到XML前缀ns2:的问题解决方案
- JAXB的应用,及如何自定义namespace的prefix(前缀)
- JAXB: How to avoid repeated namespace definition for xmlns:xsi
- JAXB-1 JAXB 概述
- Jakarta XML Binding
Jaxb 转换方案
处理麻烦点
- 命名空间前缀问题
- CDATA 转义问题
定义 package-info.java
解决命名中自定义前缀及程序生成的前缀
1 | "https://www.bytedusk.com", (namespace = |
前缀问题主要在于 NamespacePrefixMapper ,未设置命名空间的项将使用程序自动生成的前缀,所以解决办法就有两种:
- 为所有的项加上命名空间
- 显式:给所有变量加注解 @XmlElement(namespace=”https://www.bytedusk.com")
- 隐式:在 package-info.java 指定 namespace = “https://www.bytedusk.com"
- 重载 NamespacePrefixMapper 根据不同命名空间返回不同前缀。
解决 CDATA 问题
- 解决 CDATA 转义的问题思路就是,在待处理的变量上加注解,通过动态代理方式,在 Jaxb 处理前做转义。
EclipseLink 提供了一种 JaxbContext 实现方式来处理 CDATA。
配置:JaxbContext 对应扫描的 package 添加 jaxb.properties,内容如下
1 | javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory |
代码中注解:
1 | (XmlAccessType.FIELD) |
- 注意:EclipseLink 2.7.4 与 Spring ORM 4.3.5 冲突