——完成Java对象和XML相互转换

前面有介绍过json-lib这个框架,在线博文:http://www.cnblogs.com/hoojo/archive/2011/04/21/2023805.html

以及Jackson这个框架,在线博文:http://www.cnblogs.com/hoojo/archive/2011/04/22/2024628.html

它们都可以完成Java对象到XML的转换,但是还不是那么的完善。

还有XStream对JSON及XML的支持,它可以对JSON或XML的完美转换。在线博文:

http://www.cnblogs.com/hoojo/archive/2011/04/22/2025197.html

以及介绍Castor来完成Java对象到xml的相互转换。在线博文:http://www.cnblogs.com/hoojo/archive/2011/04/25/2026819.html

这次介绍Jaxb2完成xml的转换,Jaxb2使用了JDK的新特性。如:Annotation、GenericType等,Jaxb2需要在即将转换的JavaBean中添加annotation注解。下面我们就来看看Jaxb2是怎么样完成Java对象到XML之间的相互转换吧。

一、 准备工作

1、 资源准备

a) 官方文档:http://www.oracle.com/technetwork/articles/javase/index-140168.html

b) Jar包下载:http://jaxb.java.net/2.2.3/JAXB2_20101209.jar

如果你有添加jdk的jar到工程中,在rt.jar中就带有jaxb2。一般情况下不用自己添加jaxb2的jar。

2、 程序前代码准备

package com.hoo.test;
 
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.hoo.entity.Account;
import com.hoo.entity.AccountBean;
import com.hoo.entity.Birthday;
import com.hoo.entity.ListBean;
import com.hoo.entity.MapBean;
 
/**
 * function:Jaxb2 完成Java和XML的编组、解组
 * @author hoojo
 * @createDate 2011-4-25 上午11:54:06
 * @file Jaxb2Test.java
 * @package com.hoo.test
 * @project WebHttpUtils
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
public class Jaxb2Test {
    private JAXBContext context = null;
    
    private StringWriter writer = null;
    private StringReader reader = null;
    
    private AccountBean bean = null;
    
    @Before
    public void init() {
        bean = new AccountBean();
        bean.setAddress("北京");
        bean.setEmail("email");
        bean.setId(1);
        bean.setName("jack");
        Birthday day = new Birthday();
        day.setBirthday("2010-11-22");
        bean.setBirthday(day);
        
        try {
            context = JAXBContext.newInstance(AccountBean.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @After
    public void destory() {
        context = null;
        bean = null;
        try {
            if (writer != null) {
                writer.flush();
                writer.close();
            }
            if (reader != null) {
                reader.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.gc();
    }
    
    public void fail(Object o) {
        System.out.println(o);
    }
    
    public void failRed(Object o) {
        System.err.println(o);
    }
}

通过JAXBContext的newInstance方法,传递一个class就可以获得一个上下文。 newInstance方法也可以传递一个xml的文件的path。通过xml文件,对class的描述进行转换。然后,就可以通过这个上下文的来创建一个Marshaller,通过Marshaller对象的marshal方法就可以转换JavaBean对象到xml。同样JAXBContext也可以创建一个Unmarshall的unmarshal方法可以进行xml到Java对象的解组。

二、 Java编组、XML解组

1、 JavaBean和XML的相互转换

代码如下:

@Test
public void testBean2XML() {
    try {
        //下面代码演示将对象转变为xml
        Marshaller mar = context.createMarshaller();
        writer = new StringWriter();
        mar.marshal(bean, writer);
        fail(writer);
        
        //下面代码演示将上面生成的xml转换为对象
        reader = new StringReader(writer.toString());
        Unmarshaller unmar = context.createUnmarshaller();
        bean = (AccountBean)unmar.unmarshal(reader);
        fail(bean);
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

上面的context是在init方法中创建的,它传递了一个AccountBean的class,这个AccountBean不是一般的普通的bean。除了它带有getter、setter方法外,还有Annotation注解。下面我们就看看这个bean的代码。

package com.hoo.entity;
 
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import com.sun.xml.internal.txw2.annotation.XmlElement;
 
@XmlRootElement(name = "account")
public class AccountBean {
    private int id;
    private String name;
    private String email;
    private String address;
    private Birthday birthday;
    
    @XmlElement
    public Birthday getBirthday() {
        return birthday;
    }
    public void setBirthday(Birthday birthday) {
        this.birthday = birthday;
    }
    
    @XmlAttribute(name = "number")
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    
    @XmlElement
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    @XmlElement
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    
    @XmlElement
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    
    @Override
    public String toString() {
        return this.name + "#" + this.id + "#" + this.address + "#" + this.birthday + "#" + this.email;
    }
}

上面的XmlRootElement是设置当前对象转换成xml后的根节点,name的值是设置根节点的名称。在getter方法上设置XmlElement表示这个方法对应的属性是一个xml元素,如果这个注解还设置了name,那么这个name就是转换后xml的名称。在一个属性上设置XmlAttribute,表示这个方法对应的属性在转换xml后是父元素的一个属性。XmlAttribute的name就是转换后xml的属性的name。

运行后,结果如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>"1">
北京
2010-11-22emailjack
jack#1#北京#2010-11-22#email

把转换后的xml和上面的AccountBean对应看看

2、 对List类型对象,进行编组、解组

@Test
public void testList2XML() {
    ListBean listBean = new ListBean();
    listBean.setName("list to xml");
    List<Object> list = new ArrayList<Object>();
    list.add(bean);
    bean = new AccountBean();
    bean.setAddress("china");
    bean.setEmail("tom@125.com");
    bean.setId(2);
    bean.setName("tom");
    Birthday day = new Birthday("2010-11-22");
    bean.setBirthday(day);
    
    Account acc = new Account();
    acc.setAddress("china");
    acc.setEmail("tom@125.com");
    acc.setId(2);
    acc.setName("tom");
    day = new Birthday("2010-11-22");
    acc.setBirthday(day);
    list.add(bean);
    list.add(acc);
    listBean.setList(list);
    
    try {
        context = JAXBContext.newInstance(ListBean.class);
        //下面代码演示将对象转变为xml
        Marshaller mar = context.createMarshaller();
        writer = new StringWriter();
        mar.marshal(listBean, writer);
        fail(writer);
        
        //下面代码演示将上面生成的xml转换为对象
        reader = new StringReader(writer.toString());
        Unmarshaller unmar = context.createUnmarshaller();
        listBean = (ListBean)unmar.unmarshal(reader);
        fail(listBean.getList().get(0));
        fail(listBean.getList().get(1));
        fail(listBean.getList().get(2));
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

你不能直接new 一个List,然后将对象放到List中。进行编组、解组,这样会出现异常情况的。你需要构建一个JavaBean,在bean中创建一个List的属性。然后在这个属性的getter方法上进行Annotation注解。下面我们看看ListBean的代码:

package com.hoo.entity;
 
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
 
@SuppressWarnings("unchecked")
@XmlRootElement(name = "list-bean")
public class ListBean {
    private String name;
    private List list;
    
    @XmlElements({
        @XmlElement(name = "account", type = Account.class),
        @XmlElement(name = "bean", type = AccountBean.class)
    })
    public List getList() {
        return list;
    }
 
    public void setList(List list) {
        this.list = list;
    }
    
    @XmlAttribute
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}

XmlElements表示是一个集合类型,然后注解在集合中存放上面类型的对象。

XmlElement表示在集合中存放的一个对象类型和元素名称。

转换后结果如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<list-bean name="list to xml">
<bean number="1"><address>北京</address><birthday><birthday>2010-11-22</birthday></birthday>
<email>email</email><name>jack</name></bean>
<bean number="2"><address>china</address><birthday><birthday>2010-11-22</birthday></birthday>
<email>tom@125.com</email><name>tom</name></bean>
<account><address>china</address><birthday><birthday>2010-11-22</birthday></birthday>
<email>tom@125.com</email><id>2</id><name>tom</name></account>
</list-bean>
jack#1#北京#2010-11-22#email
tom#2#china#2010-11-22#tom@125.com
2#tom#tom@125.com#china#2010-11-22

转换后的XML和Bean的注解的描述是一样的吧。

2、 对Map集合进行解组、编组

/**
 * <b>function:</b>Map需要自己实现,可以构造一个简单的Map对象实现
 * http://metro.1045641.n5.nabble.com/Does-JAXB-2-0-support-Map-td1058084.html
 * @author hoojo
 * @createDate 2010-12-1 上午10:23:26
 */
@Test
public void testMap2XML() {
    MapBean mapBean = new MapBean();
    HashMap<String, AccountBean> map = new HashMap<String, AccountBean>();
    map.put("NO1", bean);
    bean = new AccountBean();
    bean.setAddress("china");
    bean.setEmail("tom@125.com");
    bean.setId(2);
    bean.setName("tom");
    Birthday day = new Birthday("2010-11-22");
    bean.setBirthday(day);
    map.put("NO2", bean);
    mapBean.setMap(map);
    
    try {
        context = JAXBContext.newInstance(MapBean.class);
        //下面代码演示将对象转变为xml
        Marshaller mar = context.createMarshaller();
        writer = new StringWriter();
        mar.marshal(mapBean, writer);
        fail(writer);
        
        //下面代码演示将上面生成的xml转换为对象
        reader = new StringReader(writer.toString());
        Unmarshaller unmar = context.createUnmarshaller();
        mapBean = (MapBean)unmar.unmarshal(reader);
        fail(mapBean.getMap());
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

下面看看MapBean的代码

package com.hoo.entity;
 
import java.util.HashMap;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.hoo.util.MapAdapter;
 
@XmlRootElement
public class MapBean {
    private HashMap<String, AccountBean> map;
    
    @XmlJavaTypeAdapter(MapAdapter.class)
    public HashMap<String, AccountBean> getMap() {
        return map;
    }
    public void setMap(HashMap<String, AccountBean> map) {
        this.map = map;
    }
}

上面的map集合的getter方法有一个XmlJavaTypeAdapter,需要传递一个Adapter的类型。

下面看看MyAdapter的代码

package com.hoo.util;
 
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.hoo.entity.AccountBean;
 
/**
 * <b>function:</b>AccountBean 编组、解组的XmlAdapter
 * @author hoojo
 * @createDate 2011-4-25 下午05:03:18
 * @file MyAdetper.java
 * @package com.hoo.util
 * @project WebHttpUtils
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
public class MapAdapter extends XmlAdapter<MapElements[], Map<String, AccountBean>> {
    public MapElements[] marshal(Map<String, AccountBean> arg0) throws Exception {
        MapElements[] mapElements = new MapElements[arg0.size()];
 
        int i = 0;
        for (Map.Entry<String, AccountBean> entry : arg0.entrySet())
            mapElements[i++] = new MapElements(entry.getKey(), entry.getValue());
 
        return mapElements;
    }
 
    public Map<String, AccountBean> unmarshal(MapElements[] arg0) throws Exception {
        Map<String, AccountBean> r = new HashMap<String, AccountBean>();
        for (MapElements mapelement : arg0)
            r.put(mapelement.key, mapelement.value);
        return r;
    }
}

MapElements

package com.hoo.util;
 
import javax.xml.bind.annotation.XmlElement;
import com.hoo.entity.AccountBean;
 
/**
 * <b>function:</b> MapElements
 * @author hoojo
 * @createDate 2011-4-25 下午05:04:04
 * @file MyElements.java
 * @package com.hoo.util
 * @project WebHttpUtils
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
public class MapElements {
    @XmlElement
    public String key;
    
    @XmlElement
    public AccountBean value;
 
    @SuppressWarnings("unused")
    private MapElements() {
    } // Required by JAXB
 
    public MapElements(String key, AccountBean value) {
        this.key = key;
        this.value = value;
    }
}

运行结果如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><mapBean><map><item><key>NO2</key><value number="2"><address>china</address>
<birthday><birthday>2010-11-22</birthday></birthday><email>tom@125.com</email><name>tom</name></value></item>
<item><key>NO1</key><value number="1"><address>北京</address><birthday><birthday>2010-11-22</birthday></birthday>
<email>email</email><name>jack</name></value></item></map></mapBean>
{NO2=tom#2#china#2010-11-22#tom@125.com, NO1=jack#1#北京#2010-11-22#email}

转载于:https://www.cnblogs.com/javaTest/archive/2011/04/26/2589350.html

Jaxb2 转换XML文档相关推荐

  1. XSLT模板转换XML文档

    XML文档只能表现数据的内容,而实际的数据则是要呈现在网页中的.使用CSS可以格式化XML文档,使它显示出来,这个内容在上一篇中已经做了详细的说明.除了CSS外,还有一种语言也可以在网页中表现出XML ...

  2. xml 文本转json java_java将XML文档转换成json格式数据

    本篇文章主要介绍了java将XML文档转换成json格式数据的示例,希望能帮助到大家. 功能 将xml文档转换成json格式数据 说明 依赖包: 1. jdom-2.0.2.jar : xml解析工具 ...

  3. java xml转html_如何在Java中将XML文档转换成HTML文档.pdf

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbsp网页设计/UI 如何在Java中将XML文档转换成HTML文档. ...

  4. xml文件怎么转换成wps_xml文件转word文档 怎么将XML文档转成WORD文档

    1.找到需要转换为word文档的xml文档. 2.选择文档并点击鼠标右键,选择"打开方式"栏目中的"WPS表格"(或者excel表格),点击确定按钮. 3.点击 ...

  5. XSLT实现XML文档转换成HTML文档

    XML文档描述了数据的结构,并且可以用自定义的标记元素描述数据意义,而且实现了记录数据的功能.如果想要将XML的数据显示在网页页面上,如何做呢? 最简单的方式就是将XML文件直接用浏览器打开,在记事本 ...

  6. 40 - xml文档与字典之间的互相转换

    1. 如何将一个字典转换为xml文档,并将该xml文档保存成文本文件 ''' dicttoxml pip install dicttixml''' import dicttoxml from xml. ...

  7. 【学习笔记】关于DOM4J:使用DOM4J解析XML文档

    一.概述 DOM4J是一个易用的.开源的库,用于XML.XPath和XSLT中.采用了Java集合框架并完全支持DOM.SAX.和JAXP. DOM4J最大的特色是使用大量的接口,主要接口都在org. ...

  8. 使用JAXP对xml文档进行DOM解析基础

    XML解析方式分为两种:dom和sax         dom:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML 的一种方式.        sax ...

  9. Dom4j 解析Xml文档及XPath查询 学习笔记

    本文查阅方法:     1.查阅目录 -- 查阅本文目录,确定想要查阅的目录标题     2.快捷"查找" -- 在当前浏览器页面,按键 "Ctrl+F" 按键 ...

最新文章

  1. ATS 5.3.0在反向代理模式下实现正向代理功能方法
  2. List复制:深拷贝和浅拷贝用法及区别
  3. 拉丁法谚讲习1-24 【ZZ】
  4. Hibernate 具体用法(自整理)
  5. MSSql-SP_who分析数据库性能
  6. Effective Java之注解优于命名模式(三十五)
  7. WordPress注册登录注册系统插件
  8. WaitForMultipleObjects函数有效值分析
  9. [源码和文档分享]基于Android的家庭学校联系平台APP开发与实现
  10. 用计算机软件绘制思维导图,一款简单好用的在线免费思维导图制作工具
  11. HNOI 2015 落忆枫音 题解
  12. 外卖联盟高级API - 怎么让小程序跳转到美团小程序领红包并下单
  13. Wephone创始人被逼身亡 -这件事始末【回来吧,兄弟】转载自和云峰公众号
  14. dns服务器地址显示fec0,DNS服务器地址为fec0
  15. 语音合成(speech synthesis)方向七:脑机接口之基于脑电图语音合成
  16. 瞬渺光电代理THZ光谱仪成功客户
  17. HPMSA2050直连服务器配置,惠普入门级存储MSA2050系列
  18. UE4/UE5 代理使用介绍
  19. 一键关闭防火墙_更省心的IoT时代网络生活:360家庭防火墙5S体验
  20. Windows XP红外线连接手机过程实例演示(转)

热门文章

  1. RabbitMQ的三大交换器详解
  2. linux文件替换命令sed使用
  3. 结构体含有指针的写入文件
  4. 用Python快速找到出现次数最多的数据
  5. 阿里安全体系获国际顶会表彰,安全技术将有九大新趋势
  6. 先弄清事物本身,再去查看评论
  7. CSS:CSS定位和浮动
  8. 《微课实战:Camtasia Studio入门精要》——第2章 录制视频 2.1 录制视频基本常识...
  9. MySQL 5.6 for Windows 解压缩版配置安装(转)
  10. python map方法