使用 JAXB(Java Architecture for XML Binding) 实现XML与Bean的相互转换
介绍
JAXB是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到 XML实例文档。
Jaxb 2.0是JDK 1.6的组成部分。我们不需要下载第三方jar包 即可做到轻松转换。Jaxb2使用了JDK的新特性,如:Annotation、GenericType等,需要在即将转换的JavaBean中添加annotation注解。
常用注解
@XmlRootElement
标识这个类或枚举类型是根元素,映射到 XML 元素中。JAXB 中的注解, 作用在类上。
@XmlElement
将java对象的属性映射为xml的节点。将没有get方法/set方法的属性映射到XML,作用在字段或方法。
@XmlAttribute
將 java 对象的属性映射为 xml 的节点的属性。
@XmlAccessorType
可能值:
FIELD: 绑定类中的(每个,没有get方法/set方法的属性也可以)非静态、非瞬态字段将会自动绑定映射到 XML,除非由 XmlTransient 注释。
NONE: 所有字段或属性都不能绑定到 XML,除非使用一些 JAXB 注释专门对它们进行注释。
PROPERTY: 绑定类中的(每个,只有有get方法/set方法的属性才可以)自动绑定映射到 XML,除非由 XmlTransient 注释。
PUBLIC_MEMBER:每个公共获取方法/设置方法对和每个公共字段将会自动绑定到 XML,除非由 XmlTransient 注释。
@XmlTransient(非瞬态)
用于标示在由Java对象映射XML时,忽略此属性,在生成的XML文件中将不出现此元素。
例子
xml内容
实体映射
xml工具类
public class JAXBUtil {
/**
* XML转换为POJO类型
*/
@SuppressWarnings("rawtypes")
public static Object unmarshall(String xml, Class clsToUnbound) throws JAXBException, UnsupportedEncodingException {
JAXBContext jc = JAXBContext.newInstance(clsToUnbound);
return unmarshall(jc, xml);
}
private static Object unmarshall(JAXBContext jc, String xml) throws JAXBException, UnsupportedEncodingException {
Unmarshaller u = jc.createUnmarshaller();
InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
return u.unmarshal(is);
}
/**
* 从流中反序列化对象。
*
* @param cls 需要反序列化的对象类型。
* @param xmlIs 流对象
* @return 经过反序列化的对象实例。
* @throws JAXBException
*/
public static Object unmarshall(InputStream xmlIs, Class<?> cls) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(cls);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Object obj = unmarshaller.unmarshal(xmlIs);
return obj;
}
@SuppressWarnings("unchecked")
public Object unmarshall(String xml, Class<? extends Object>... classes) throws JAXBException, IOException {
InputStream is = new ByteArrayInputStream(xml.getBytes());
JAXBContext jc = JAXBContext.newInstance(classes);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
Object obj = unmarshaller.unmarshal(is);
return obj;
}
/**
* POJO类型转换为XML
*
* @param jc
* @param serObj
* @param formatOutput 是否格式化
* @param fragment 是否隐藏报文头
* @return
* @throws JAXBException
* @throws PropertyException
*/
private static String marshall(JAXBContext jc, Object serObj, boolean formatOutput, boolean fragment) throws JAXBException, PropertyException {
StringWriter out = new StringWriter();
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, formatOutput);
m.setProperty(Marshaller.JAXB_FRAGMENT, fragment);
m.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
m.marshal(serObj, out);
String tmp = out.toString();
return tmp;
}
@SuppressWarnings("rawtypes")
public static String marshall(Object serObj, Class clsToBound) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(clsToBound);
return marshall(jc, serObj, true, false);
}
public static String marshall(Object serObj, boolean formatOutput, boolean fragment) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(serObj.getClass());
return marshall(jc, serObj, formatOutput, fragment);
}
public static String marshall(Object serObj, boolean formatOutput) throws JAXBException {
return marshall(serObj, formatOutput, false);
}
/**
* 将类序列化到流中。
*
* @param contextPath 需要序列化到类名
* @param obj 需要序列化的实例对象
* @param stream 需要序列化到的流对象。
* @throws JAXBException
*/
public static void marshall(String contextPath, Object obj, OutputStream stream) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(contextPath);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
m.marshal(obj, stream);
}
}
测试代码
结果
bean = Forecast_Content(PubListName=南海海域预报, seaAreas=[SeaArea(items=[Item(NameCHS=狮子洋海域, NameEN=shizi sea, forecastContentList=[ForecastContent(time=23日 20:00, WaveHeightStr=0.1-0.3)]), Item(NameCHS=内伶仃洋海域, NameEN=lingding sea, forecastContentList=[ForecastContent(time=23日 20:00, WaveHeightStr=0.2-0.6)]), Item(NameCHS=中华白海豚保护区, NameEN=, forecastContentList=[ForecastContent(time=23日 20:00, WaveHeightStr=0.3-0.7)]), Item(NameCHS=外伶仃洋海域, NameEN=outer lingding sea, forecastContentList=[ForecastContent(time=23日 20:00, WaveHeightStr=0.5-0.8)]), Item(NameCHS=桂山岛海域, NameEN=guishan, forecastContentList=[ForecastContent(time=23日 20:00, WaveHeightStr=0.7-1.0)])])])