注意:我是EclipseLink JAXB (MOXy) 领导,也是JAXB (JSR-222) 专家组的成员。
EclipseLink JAXB (MOXy) 支持将单个对象模型映射到具有相同元数据的 XML 和 JSON:
许可证信息
域模型
下面是我们将用于此示例的域模型。对于这个例子,我只是使用标准 JAXB (JSR-222) 注释,这些注释自 Java SE 6 起就在 JDK/JRE 中可用。
客户
package forum658936;
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
String firstName;
@XmlElement(nillable=true)
String lastName;
@XmlElement(name="phone-number")
List<PhoneNumber> phoneNumbers;
}
电话号码
package forum658936;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {
@XmlAttribute
int id;
@XmlValue
String number;
}
jaxb.properties
要将 MOXy 指定为您的 JAXB 提供程序,您需要在与域模型相同的包中包含一个名为 jaxb.properties 的文件,并使用以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
XML
input.xml
这是我们的演示代码将读取并转换为域对象的 XML。
<?xml version="1.0" encoding="UTF-8"?>
<customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<firstName>Jane</firstName>
<lastName xsi:nil="true"/>
<phone-number id="123">555-1234</phone-number>
</customer>
关于 XML 的注意事项:
JSON
输出
下面是运行演示代码输出的 JSON。
{
"firstName" : "Jane",
"lastName" : null,
"phone-number" : [ {
"id" : 123,
"value" : "555-1234"
} ]
}
关于 JSON 的注意事项:
-
null 值用于表示lastName 为空。不存在 xsi:nil 属性。
- 电话号码集合的大小为 1,并正确地用方括号绑定。许多库错误地将大小为 1 的集合视为 JSON 对象。
-
int 类型的 property 被正确编组,不带引号。
- 在 XML 表示中
id 是一个属性,但在 JSON 表示中不需要特别表示。
演示代码
在下面的演示代码中,我们会将 XML 文档转换为对象,然后将这些相同的实例转换为 JSON。
演示
MOXy 不只是解释 JAXB 注释,它是一个 JAXB 实现,因此使用标准 JAXB 运行时 API。通过在 Marshaller 上指定 MOXy 指定属性来启用 JSON 绑定。
package forum658936;
import java.io.File;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum658936/input.xml");
Customer customer = (Customer) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
marshaller.marshal(customer, System.out);
}
}