博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Jaxb2 转换XML文档
阅读量:4494 次
发布时间:2019-06-08

本文共 10774 字,大约阅读时间需要 35 分钟。

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

前面有介绍过json-lib这个框架,在线博文:

以及Jackson这个框架,在线博文:

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

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

以及介绍Castor来完成Java对象到xml的相互转换。在线博文:

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

一、 准备工作

1、 资源准备

a) 官方文档:

b) 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。

运行后,结果如下:

北京
2010-11-22
email
jack
jack#1#北京#2010-11-22#email

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

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

@Test
public void testList2XML() {
ListBean listBean = new ListBean();
listBean.setName("list to xml");
List list = new ArrayList();
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表示在集合中存放的一个对象类型和元素名称。

转换后结果如下:

北京
2010-11-22
email
jack
china
2010-11-22
tom@125.com
tom
china
2010-11-22
tom@125.com
2
tom
 
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集合进行解组、编组

/**
* function: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
map = new HashMap
();
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
map;
 
@XmlJavaTypeAdapter(MapAdapter.class)
public HashMap
getMap() {
return map;
}
public void setMap(HashMap
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;
 
/**
* function: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
> {
public MapElements[] marshal(Map
arg0) throws Exception {
MapElements[] mapElements = new MapElements[arg0.size()];
 
int i = 0;
for (Map.Entry
entry : arg0.entrySet())
mapElements[i++] = new MapElements(entry.getKey(), entry.getValue());
 
return mapElements;
}
 
public Map
unmarshal(MapElements[] arg0) throws Exception {
Map
r = new HashMap
();
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;
 
/**
* function: 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;
}
}

运行结果如下:

NO2
china
2010-11-22
tom@125.com
tom
NO1
北京
2010-11-22
email
jack
{NO2=tom#2#china#2010-11-22#tom@125.com, NO1=jack#1#北京#2010-11-22#email}

转载于:https://www.cnblogs.com/hibernate3-example/archive/2012/05/09/2492346.html

你可能感兴趣的文章
PowerDesigner 逆向工程 Could not Initialize JavaVM!
查看>>
用python抓取oj题目(3)——django显示
查看>>
no.5京东物流系统架构系统演讲中的最佳实践读后感
查看>>
JAVA AES加密算法实现代码
查看>>
STL 之map解决 Message Flood(原字典树问题)
查看>>
Spring Maven——pom.xml及settings.xml配置
查看>>
软件测试基本知识
查看>>
nodejs项目windows下开机自启动
查看>>
1136 - Division by 3
查看>>
1_基本语法之关键字和保留字_标识符_注释
查看>>
Git知识总览(二) git常用命令概览
查看>>
新的移动端框架
查看>>
最近的总结
查看>>
NHiberante的优缺点
查看>>
SQLite 入门教程(二)创建、修改、删除表
查看>>
gzip: stdin: unexpected end of file tar: Unexpected EOF in archive
查看>>
文件系统中的权限含义
查看>>
Crossin 8-3;8-4
查看>>
[编织消息框架][JAVA核心技术]动态代理应用5-javassist
查看>>
关于X系统
查看>>