JAXB 解决XML与JavaBean的互换
声明
版权所有,转载请注明出处
文章概要
基于JAXB2 的xml bean 转换工具
正文
运行环境
JDK,Dom4j
JAXB 实现xml和javabean的编组和解组
/**
* 基于JAXB2 的xml bean 转换工具
* @author Administrator
*
*/
public class JaxbUtil {
public static String bean2xml(Object bean){
try {
JAXBContext context = JAXBContext.newInstance(bean.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Writer writer = new StringWriter();
marshaller.marshal(bean, writer);
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static T xml2Bean(String xml,Class clazz){
T t = null;
try {
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = context.createUnmarshaller();
t = (T) unmarshaller.unmarshal(new StringReader(xml));
return t;
} catch (Exception e) {
e.printStackTrace();
}
return t;
}
}
测试用例: JavaBean
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement()
@XmlType(propOrder = {})
public class GeneralMessageHead implements MessageHead{
/**
*
*/
private String RequestType;
private String CompanyCode;
private String SerialNo;
private String TimeStamp;
private String DataType;
//省略getter和setter
}
测试类
public class JaxbUtilTest {
@Test
public void testBean2xml() {
String xml = JaxbUtil.bean2xml(TestHandel.getRequestHead());
System.out.println(xml);
}
@Test
public void testXml2Bean() {
String xml = " HisUpload00000020150825150212012320150102010101P";
GeneralMessageHead a = JaxbUtil.xml2Bean(xml, GeneralMessageHead.class);
System.out.println(a.getCompanyCode());
}
}
测试运行结果
000000
HisUpload
000000
201508251502120123
20150102010101
P
JAXB 常用annotation说明:
@XmlType
@XmlElement
@XmlRootElement
@XmlAttribute
@XmlAccessorType
@XmlAccessorOrder
@XmlTransient
@XmlJavaTypeAdapter
复杂Bean示例
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement()
@XmlType(propOrder = {})
public enum EnumBean {
MON, TUE, WED, THU, FRI, SAT, SUN;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement()
@XmlType(propOrder = {})
public class SimpleBean {
private String stringType;
private double doubleType;
public String getStringType() {
return stringType;
}
public void setStringType(String stringType) {
this.stringType = stringType;
}
public double getDoubleType() {
return doubleType;
}
public void setDoubleType(double doubleType) {
this.doubleType = doubleType;
}
}
/**
* 该Bean包含了:
* 引用对象
* 基本数据类型
* 枚举
* 数组
* 集合[List,Set,Map]
*
*
*
*/
/**
* @XmlAccessorType用于指定由java对象生成xml文件时对java对象属性的访问方式,有四个枚举值:
* XmlAccessType.FIELD:java对象中的所有成员变量
XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量
XmlAccessType.PUBLIC_MEMBER:java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量
XmlAccessType.NONE:java对象的所有(未加注解的)属性都不映射为xml的元素
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement()
@XmlType(propOrder = {})
/**
@XmlAccessorOrder用于对java对象生成的xml元素进行排序.它有两个属性值:
XmlAccessOrder.ALPHABETICAL:对生成的xml元素按字母书序排序
XmlAccessOrder.UNDEFINED:不排序
*/
//@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
public class ComplexBean {
@XmlElement(name="SimpleBean")//修改元素名称
SimpleBean otherBean;
@XmlAttribute(name="intType")//使其为根节点属性
int intType;
@XmlTransient//忽略属性
long longType;
float floatType;
double doubleType;
boolean booleanType;
char charType;
String stringType;
@XmlJavaTypeAdapter(value=jaxb.FormatDate.class)//自定义转换
Date dateType;
EnumBean enumType;
String[] stringArrayType;
SimpleBean[] simpleBeanArrayType;
List stringListType;
Set stringSetType;
Map stringMapType;
Map beanMapTyep;
//省略getter和setter
}
public class FormatDate extends XmlAdapter {
private SimpleDateFormat sdf = new SimpleDateFormat("YYYY/MM/dd HH:mm:ss");
@Override
public String marshal(Date v) throws Exception {
return sdf.format(v);
}
@Override
public Date unmarshal(String v) throws Exception {
return sdf.parse(v);
}
}
测试代码
SimpleBean simpleBean = new SimpleBean();
simpleBean.setStringType("string");
simpleBean.setDoubleType(1.11);
ComplexBean complexBean = new ComplexBean();
complexBean.setOtherBean(simpleBean);
complexBean.setIntType(1);
complexBean.setLongType(2);
complexBean.setFloatType(3);
complexBean.setDoubleType(4.23);
complexBean.setCharType('5');
complexBean.setBooleanType(true);
complexBean.setStringType("string");
complexBean.setDateType(new Date());
complexBean.setEnumType(EnumBean.MON);
String[] stringArrayType = new String[]{"str1","str2","str3"};
SimpleBean[] simpleBeanArrayType = new SimpleBean[]{simpleBean};
complexBean.setStringArrayType(stringArrayType);
complexBean.setSimpleBeanArrayType(simpleBeanArrayType);
List stringListType = new ArrayList();
stringListType.add("list1");stringListType.add("list2");
Set stringSetType = new HashSet(stringListType);
Map stringMapType = new HashMap<>();
stringMapType.put("key", "value");
complexBean.setStringListType(stringListType);
complexBean.setStringSetType(stringSetType);
complexBean.setStringMapType(stringMapType);
Map beanMapTyep = new HashMap<>();
beanMapTyep.put("key", simpleBean);
complexBean.setBeanMapTyep(beanMapTyep);
String xml = JaxbUtil.bean2xml(complexBean);
System.out.println(xml);
使用Dom4j解析XML
对我来说,使用JDK的XML解析类很不方便.为了解决复杂的XML Bean组合与拆分问题,我通常使用Dom4j提取出Bean对应的DOM元素节点,然后再用JAXB解析为Bean实例.
反过来,多个Bean组合的XML文档,先使用JAXB将Bean转为XML,在使用Dom4j组合这些XML.
Dom4j很方便的一点就是可以使用XPath直接,准确的定位元素节点.
参考资料