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> T xml2Bean(String xml,Class<T> 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 = " <generalMessageHead> <RequestType>HisUpload</RequestType> <CompanyCode>000000</CompanyCode> <SerialNo>201508251502120123</SerialNo> <TimeStamp>20150102010101</TimeStamp> <DataType>P</DataType> </generalMessageHead>"; GeneralMessageHead a = JaxbUtil.xml2Bean(xml,GeneralMessageHead.class); System.out.println(a.getCompanyCode()); } }
测试运行结果
000000 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <generalMessageHead> <RequestType>HisUpload</RequestType> <CompanyCode>000000</CompanyCode> <SerialNo>201508251502120123</SerialNo> <TimeStamp>20150102010101</TimeStamp> <DataType>P</DataType> </generalMessageHead>
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<String> stringListType; Set<String> stringSetType; Map<String,String> stringMapType; Map<String,SimpleBean> beanMapTyep; //省略getter和setter }
public class FormatDate extends XmlAdapter<String,Date> { 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<String> stringListType = new ArrayList<String>(); stringListType.add("list1");stringListType.add("list2"); Set<String> stringSetType = new HashSet<String>(stringListType); Map<String,String> stringMapType = new HashMap<>(); stringMapType.put("key","value"); complexBean.setStringListType(stringListType); complexBean.setStringSetType(stringSetType); complexBean.setStringMapType(stringMapType); Map<String,SimpleBean> 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直接,准确的定位元素节点.
###参考资料