JAXB2 转换XML文档
——完成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 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 void destory() { context = null; bean = null; if (writer != null) {
writer.flush(); writer.close(); } if (reader != null) { reader.close(); } } catch (IOException e) {
e.printStackTrace(); } System.gc(); void fail(Object o) { System.out.println(o); 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
void testBean2XML() { //下面代码演示将对象转变为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")
class AccountBean { private int id;
private String name; private String email; private String address; private Birthday birthday; @XmlElement public Birthday getBirthday() { return birthday; void setBirthday(Birthday birthday) { this.birthday = birthday; @XmlAttribute(name = "number")
int getId() { return id; void setId(int id) {
this.id = id; public String getName() { return name; void setName(String name) { this.name = name; public String getEmail() { return email; void setEmail(String email) { this.email = email; public String getAddress() { return address; 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"?><account number="1"<address>北京</>
<birthday>2010-11-22</birthday<email>email</email<name>jack</name</accountjack#1#北京#2010-11-22#email 把转换后的xml和上面的AccountBean对应看看 2、 对List类型对象,进行编组、解组 void testList2XML() {
ListBean listBean = new ListBean();
listBean.setName("list to xml");
List<Object> list = new ArrayList<Object>();
list.add(bean); bean = bean.setAddress("china");
bean.setEmail("tom@125.com");
bean.setId(2); bean.setName("tom");
Birthday day = new Birthday( bean.setBirthday(day); Account acc = new Account();
acc.setAddress( acc.setEmail( acc.setId(2);
acc.setName( day = acc.setBirthday(day);
list.add(acc); listBean.setList(list); context = JAXBContext.newInstance(ListBean. mar.marshal(listBean,monospace; direction:ltr; font-size:10pt; overflow:visible; background-color:white"> listBean = (ListBean)unmar.unmarshal(reader);
fail(listBean.getList().get(0)); fail(listBean.getList().get(1)); fail(listBean.getList().get(2)); } 你不能直接new 一个List,然后将对象放到List中。进行编组、解组,这样会出现异常情况的。你需要构建一个JavaBean,在bean中创建一个List的属性。然后在这个属性的getter方法上进行Annotation注解。下面我们看看ListBean的代码: import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements; @SuppressWarnings("unchecked")
@XmlRootElement(name = "list-bean")
class ListBean { private List list; @XmlElements({ @XmlElement(name = "account",type = Account.class), @XmlElement(name = "bean",type = AccountBean.class) }) public List getList() { return list; void setList(List list) { this.list = list; @XmlAttribute } XmlElements表示是一个集合类型,然后注解在集合中存放上面类型的对象。 XmlElement表示在集合中存放的一个对象类型和元素名称。 转换后结果如下: <list-bean name="list to xml"<bean number="1"</bean<bean number="2">china>tom@125.com>tom<account<id>2</id</list-beanjack#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 * @createDate 2010-12-1 上午10:23:26 void testMap2XML() { MapBean mapBean = new MapBean();
HashMap<String,AccountBean> map = new HashMap<String,AccountBean>();
map.put("NO1",bean);
bean = bean.setAddress( bean.setEmail( bean.setId(2);
bean.setName( Birthday day = bean.setBirthday(day);
"NO2",244)"> mapBean.setMap(map); context = JAXBContext.newInstance(MapBean. mar.marshal(mapBean,monospace; direction:ltr; font-size:10pt; overflow:visible; background-color:white"> mapBean = (MapBean)unmar.unmarshal(reader);
fail(mapBean.getMap()); } 下面看看MapBean的代码 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.hoo.util.MapAdapter; @XmlRootElement class MapBean { private HashMap<String,AccountBean> map; @XmlJavaTypeAdapter(MapAdapter.public HashMap<String,AccountBean> getMap() {
return map; void setMap(HashMap<String,AccountBean> map) { this.map = map; } 上面的map集合的getter方法有一个XmlJavaTypeAdapter,需要传递一个Adapter的类型。 下面看看MyAdapter的代码 package com.hoo.util;
import javax.xml.bind.annotation.adapters.XmlAdapter; * <b>function:</b>AccountBean 编组、解组的XmlAdapter * @createDate 2011-4-25 下午05:03:18 * @file MyAdetper.java * @package com.hoo.util 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) Map<String,AccountBean> r = for (MapElements mapelement : arg0)
r.put(mapelement.key,mapelement.value); return r; } MapElements * <b>function:</b> MapElements
* @createDate 2011-4-25 下午05:04:04 * @file MyElements.java class MapElements { @XmlElement public String key; public AccountBean value; @SuppressWarnings("unused")
private MapElements() { } // Required by JAXB
public MapElements(String key,AccountBean value) { this.key = key; this.value = value; } 运行结果如下: <mapBeanmap<item<key>NO2</key<value number="2"</value</item>NO1<value number="1"</mapBean{NO2=tom#2#china#2010-11-22#tom@125.com,NO1=jack#1#北京#2010-11-22#email}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |