JAXB(Java Architecture for XML Binding)能够帮助大家快速的进行Object与XML进行相互映射,其中主要使用到的是JAXBContext 、Marshaller、Unmarshaller三个接口。
JAXBContext 类提供到 JAXB API 的客户端入口点。它提供了管理实现 JAXB 绑定框架操作所需的 XML/Java 绑定信息的抽象,这些操作包括:解组、编组和验证。客户端应用程序通常使用以下两种风格的 newInstance ()方法之一来获得此类的新实例。
1.JAXBContext.newInstance( “com.acme.foo:com.acme.bar” )
JAXBContext 实例是根据冒号分隔的 Java 包名称的列表进行初始化的。每个 java 包都包含 JAXB 映射类、模式派生类和/或用户注释类。此外,java 包可能包含必须处理的 JAXB 包注释。
2.JAXBContext.newInstance( com.acme.foo.Foo.class )
JAXBContext 实例是使用作为参数传递的类以及可从这些类静态获得的类来实现初始化的。
Marshaller 类使客户端应用程序能够将 Java 内容转换回 XML 数据。
可以使用File、DOM Node、java.io.OutputStream、java.io.Writer等。
1.编组到File中
OutputStream os = new FileOutputStream( “nosferatu.xml” );
m.marshal( element, os );
2.编组到DOM Node中
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
m.marshal( element, doc );
3.编组到java.io.OutputStream中
m.marshal( element, System.out );
4. 编组到java.io.Writer
m.marshal( element, new PrintWriter( System.out ) );
1.jaxb.encoding:值必须是 java.lang.String
编组 XML 数据时使用的输出编码。默认情况下,如果未指定此属性,则 Marshaller 将使用 “UTF-8”。
2.jaxb.formatted.output:值必须是 java.lang.Boolean
此属性控制 Marshaller 是否使用换行和缩排对得到的 XML 数据进行格式化。此属性为 true 值表示可读性强的缩排 xml 数据,而属性值为 false 则表示未格式化的 xml 数据。如果未指定此属性,则 Marshaller 将该属性值默认为 false(未格式化)。
3.jaxb.schemaLocation:值必须是 java.lang.String
此属性允许客户端应用程序在生成的 XML 数据中指定 xsi:schemaLocation 属性。
4.jaxb.noNamespaceSchemaLocation:值必须是 java.lang.String
此属性允许客户端应用程序在生成的 XML 数据中指定 xsi:noNamespaceSchemaLocation 属性。
5.jaxb.fragment:值必须是 java.lang.Boolean
此属性决定 Marshaller 是否将生成文档级事件。如果未指定该属性,则默认为 false。
Unmarshaller 类管理将 XML 数据反序列化为新创建的 Java 内容树的过程,并可在解组时有选择地验证 XML 数据。
同样Unmarshaller 也支持多种格式的解组。
下面就开始进行Object和XML的相互映射吧。
直接上代码
public class JaxpUtil {
/**
* @Description 对象转化XML
* @param obj 待转化对象
* @throws Exception
* @return String 组成的字符串
*/
public static String toXML(Object obj) throws Exception {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setListener(new JaxpMarshallerListener());
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");// //编码格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// 是否格式化生成的xml串
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);// 是否省略xm头声明信息
StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
String xml = writer.toString();
return xml;
}
/**
* @Description XML转化为对象
* @param xml 传入的XML报文
* @param valueType 需要返回的cls
* @throws JAXBException 参数
* @return T 解析完成对象
*/
@SuppressWarnings("unchecked")
public static T fromXML(String xml, Class valueType) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(valueType);
Unmarshaller unmarshaller = context.createUnmarshaller();
return (T) unmarshaller.unmarshal(new StringReader(xml));
}
}
然后需要进行xml映射的对象必须要添加XML的注解才能够进行转换。基本常用的注解如下:
1.@XmlRootElement,将Java类或枚举映射成XML元素根节点,是唯一一个必须注解,name属性指定根节点名称,不指定默认为类名的小写;
2.@XmlElement,将Java类的一个属性映射为XML节点元素,name属性可自定义元素名;这个注解如果添加在字段上,那么字段必须先要序列化。所以要和@XmlAccessorType配套使用才可以。但是如果添加到set/get方法上则可以执行。
3.@XmlAttribute,将Java类的一个属性映射为XML节点元素的属性,name属性可自定义属性名;
4.@XmlType,将Java类或枚举类型映射到XML模式类型,常与@XmlRootElement、@XmlAccessorType共用,propOrder属性定义字段生成的XML节点顺序;
5.@XmlAccessorType,控制字段或属性的序列化。属性XmlAccessType有4个常量值:XmlAccessType.FIELD表示JAXB将自动绑定Java类中的每个非静态的(static);XmlAccessType.PROPERTY表示java对象中所有通过getter/setter方式绑定成属性到XML;注解中如果属性值为XmlAccessType.FIELD,则表示通过成员变量来映射,set/get方法上的映射注解就是多余的,所以如果此时set/get方法上再标注元素或者属性映射注解,将抛属性重复性异常;属性值为XmlAccessType.NONE不映射为XML元素的前提是Java字段或set/get方法上都没有映射注解;XmlAccessType.PUBLIC_MEMBER表示Java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量,该值为默认值;
6.@XmlAccessorOrder,控制JAXB 绑定类中属性和字段的排序,有两个属性,AccessorOrder.ALPHABETICAL——对生成的XML元素按字母书序排序,XmlAccessOrder.UNDEFINED——不排序,默认为该值;
7.@XmlJavaTypeAdapter,自定义适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),解决日期(Date),数字(Number)格式化问题;
8.@XmlElementWrapper ,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器),该注解只能用在集合上;
9.@XmlTransient ,用于标示在由Java对象映射XML时,忽略此属性,在生成的XML文件中将不出现此元素。
所以我需要转换的类定义为如下
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ProcessManagerResponse", propOrder={"header", "actions", "results", "outputs"})
@XmlRootElement(name="ProcessManagerResponse")
public class PMResponseInfo {
@XmlElement(name="Application_Header")
private ApplicationHeader header;
@XmlElement(name="Instinct_Actions")
private InstinctActions actions;
@XmlElement(name="PM_Results")
private PmResults results;
@XmlElement(name="PM_Outputs")
private PMOutputs outputs;
public ApplicationHeader getHeader() {
return header;
}
public void setHeader(ApplicationHeader header) {
this.header = header;
}
public InstinctActions getActions() {
return actions;
}
public void setActions(InstinctActions actions) {
this.actions = actions;
}
public PmResults getResults() {
return results;
}
public void setResults(PmResults results) {
this.results = results;
}
public PMOutputs getOutputs() {
return outputs;
}
public void setOutputs(PMOutputs outputs) {
this.outputs = outputs;
}
@Override
public String toString() {
return "PMVerifyResponseInfo [header=" + header + ", actions="
+ actions + ", results=" + results + ", outputs=" + outputs
+ "]";
}
}
剩下的直接调用即可。