利用JAXB實現java對象和xml的相互轉換

一:JAXB註解 

JAXB(Java API for XML Binding),提供了一個快速便捷的方式將Java對象與XML進行轉換。JAXB 可以實現Java對象與XML的相互轉換,在JAXB中,將一個Java對象轉換爲XML的過程稱之爲Marshal,將XML轉換爲Java對象的過程稱之爲UnMarshal。我們可以通過在 Java 類中標註註解的方式將一個Java對象綁定到一段XML,來說明java對象和XML元素的對應關係。

@XmlRootElement   將一個Java類映射爲一段XML的根節點
參數:  name  定義這個根節點的名稱
        namespace   定義這個根節點命名空間
@XmlAccessorType   定義映射這個類中的何種類型需要映射到XML。可接收四個參數,分別是:
參數:  XmlAccessType.FIELD:     映射這個類中的所有字段到XML
        XmlAccessType.PROPERTY:  映射這個類中的屬性(get/set方法)到XML
        XmlAccessType.PUBLIC_MEMBER:  將這個類中的所有public的field或property同時映射到XML(默認)
      XmlAccessType.NONE:   不映射
@XmlElement    指定一個字段或get/set方法映射到XML的節點。如,當一個類的XmlAccessorType 被標註爲PROPERTY時,在某一個沒有get/set方法的字段上標註此註解,即可將該字段映射到XML。
參數:  defaultValue  指定節點默認值
        name          指定節點名稱
        namespace     指定節點命名空間
        required      是否必須(默認爲false)
        nillable      該字段是否包含 nillable="true" 屬性(默認爲false)
        type          定義該字段或屬性的關聯類型
@XmlAttribute  指定一個字段或get/set方法映射到XML的屬性。
參數:  name         指定屬性名稱
        namespace    指定屬性命名空間
        required     是否必須(默認爲false)
<strong>@XmlTransient</strong>   定義某一字段或屬性不需要被映射爲XML。如,當一個類的XmlAccessorType 被標註爲PROPERTY時,在某一get/set方法的字段上標註此註解,那麼該屬性則不會被映射。
@XmlType   定義映射的一些相關規則
參數:  propOrder        指定映射XML時的節點順序
        factoryClass     指定UnMarshal時生成映射類實例所需的工廠類,默認爲這個類本身
        factoryMethod    指定工廠類的工廠方法
        name             定義XML Schema中type的名稱
        namespace        指定Schema中的命名空間
@XmlElementWrapper   爲數組元素或集合元素定義一個父節點。如,類中有一元素爲List items,若不加此註解,該元素將被映射爲
 <items>...</items>
 <items>...</items>
這種形式,此註解可將這個元素進行包裝,如:
@XmlElementWrapper(name="items")
@XmlElement(name="item")
public List items;
將會生成這樣的XML樣式:
    <items>
	<item>...</item>
        <item>...</item>
    </items>
@XmlJavaTypeAdapter  自定義某一字段或屬性映射到XML的適配器。如,類中包含一個接口,我們可以定義一個適配器(繼承自 javax.xml.bind.annotation.adapters.XmlAdapter類),指定這個接口如何映射到XML。
@XmlSchema   配置整個包的namespace,這個註解需放在package-info.java文件中。


二:實例

定義context類,其中包含Datesource和一個NewWs組成的set

package jaxb;

import java.util.Set;

import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Context", propOrder = { "datasource", "newsWs" })
@XmlRootElement(name = "context")
public class Context {
    @XmlElement(name = "datasource")
    private Datasource datasource;

    @XmlElementWrapper(name = "news-ws-define")
    @XmlElement(name = "news-ws")
    private Set<NewsWs> newsWs;

    public Context() {
        super();
    }

    public Context(Datasource datasource, Set<NewsWs> newsWs) {
        super();
        this.datasource = datasource;
        this.newsWs = newsWs;
    }

    public Datasource getDatasource() {
        return datasource;
    }

    public void setDatasource(Datasource datasource) {
        this.datasource = datasource;
    }

    public Set<NewsWs> getNewsWs() {
        return newsWs;
    }

    public void setNewsWs(Set<NewsWs> newsWs) {
        this.newsWs = newsWs;
    }

    @Override
    public String toString() {
        return "Conext [datasource=" + datasource + ", newsWs=" + newsWs + "]";
    }
}

分別定義Datesource類和NewWs類

package jaxb;

import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlType(propOrder = { "dbtype", "url", "user", "password" })
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "datasource")
public class Datasource {
    @XmlElement(name = "db-type")
    private String dbtype;

    @XmlElement(name = "url")
    private String url;

    @XmlElement(name = "user")
    private String user;

    @XmlElement(name = "password")
    private String password;

    public Datasource() {
        super();
    }

    public Datasource(String dbtype, String url, String user, String password) {
        super();
        this.dbtype = dbtype;
        this.url = url;
        this.user = user;
        this.password = password;
    }

    public String getDbtype() {
        return dbtype;
    }

    public void setDbtype(String dbtype) {
        this.dbtype = dbtype;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "Datasource [dbtype=" + dbtype + ", url=" + url + ", user=" + user + ", password=" + password + "]";
    }
}

package jaxb;

import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlType(propOrder = { "sql", "time", "column", "allyCode" })
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "news-ws")
public class NewsWs {
    @XmlElement(name = "sql")
    private String sql;

    @XmlElement(name = "time")
    private String time;

    @XmlElement(name = "column")
    private String column;

    @XmlElement(name = "ally-code")
    private String allyCode;

    public NewsWs() {
        super();
    }

    public NewsWs(String sql, String time, String column, String allyCode) {
        super();
        this.sql = sql;
        this.time = time;
        this.column = column;
        this.allyCode = allyCode;
    }

    public String getSql() {
        return sql;
    }

    public void setSql(String sql) {
        this.sql = sql;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getColumn() {
        return column;
    }

    public void setColumn(String column) {
        this.column = column;
    }

    public String getAllyCode() {
        return allyCode;
    }

    public void setAllyCode(String allyCode) {
        this.allyCode = allyCode;
    }

    @Override
    public String toString() {
        return "NewsWs [sql=" + sql + ", time=" + time + ", column=" + column + ", allyCode=" + allyCode + "]";
    }
}
實現一個JAXBUtil工具類

package jaxb.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class JAXBUtil {
    private static final String ENCODING = "UTF-8";
    private static final Log logger = LogFactory.getLog(JAXBUtil.class);

    public static <T> T formXML(Class<T> clazz, String xml) {
        JAXBContext jaxbContext = null;
        T object = null;
        if (xml != null && !"".equals(xml)) {
            try {
                jaxbContext = JAXBContext.newInstance(clazz);
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(xml.getBytes(ENCODING));
                Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
                JAXBElement<T> jaxbElement = unmarshaller.unmarshal(new StreamSource(byteArrayInputStream), clazz);
                object = (T) jaxbElement.getValue();
            } catch (Exception e) {
                logger.error("error when unmarshalling from a xml string");
            }
        }
        return object;
    }

    public static <T> String toXML(T object) {
        String xml = "";
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
            Marshaller marshaller = jaxbContext.createMarshaller();
            // 是否格式化生成xml
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            // 設置編碼方式
            marshaller.setProperty(Marshaller.JAXB_ENCODING, ENCODING);

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            marshaller.marshal(object, byteArrayOutputStream);
            byte[] buf = byteArrayOutputStream.toByteArray();
            xml = new String(buf, 0, buf.length, ENCODING);
        } catch (Exception e) {
            logger.error("error when marshalling to a xml string");
        }
        return xml;
    }
}


測試函數:
package jaxb;

import java.util.HashSet;
import java.util.Set;

import jaxb.util.JAXBUtil;

public class JaxbTest {
    public static void main(String[] args) throws Exception {
        Set<NewsWs> set = new HashSet<NewsWs>();
        Datasource datasource = new Datasource("Mysql", "http://127.0.0.1:8080/hello", "root", "123");
        NewsWs newsWs1 = new NewsWs("sql1", "2013年7月13日", "新聞內容1", "驗證1");
        NewsWs newsWs2 = new NewsWs("sql2", "2013年7月14日", "新聞內容2", "");
        NewsWs newsWs3 = new NewsWs("sql3", "2013年7月15日", "新聞內容3", "驗證1");
        set.add(newsWs1);
        set.add(newsWs2);
        set.add(newsWs3);

        Context context = new Context(datasource, set);
        String xml = JAXBUtil.toXML(context);
        System.out.println(xml);
        
        Context context1 = JAXBUtil.formXML(Context.class , xml);
        System.out.println(context1.getDatasource().toString());
        Set<NewsWs> set1 = context1.getNewsWs();
        for (NewsWs ws : set1) {
            System.out.println("**************");
            System.out.println(ws.getSql());
            System.out.println(ws.getTime());
            System.out.println(ws.getColumn());
            System.out.println(ws.getAllyCode());
        }
    }
}


運行結果如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<context>
    <datasource>
        <db-type>Mysql</db-type>
        <url>http://127.0.0.1:8080/hello</url>
        <user>root</user>
        <password>123</password>
    </datasource>
    <news-ws-define>
        <news-ws>
            <sql>sql2</sql>
            <time>2013年7月14日</time>
            <column>新聞內容2</column>
            <ally-code></ally-code>
        </news-ws>
        <news-ws>
            <sql>sql1</sql>
            <time>2013年7月13日</time>
            <column>新聞內容1</column>
            <ally-code>驗證1</ally-code>
        </news-ws>
        <news-ws>
            <sql>sql3</sql>
            <time>2013年7月15日</time>
            <column>新聞內容3</column>
            <ally-code>驗證1</ally-code>
        </news-ws>
    </news-ws-define>
</context>

Datasource [dbtype=Mysql, url=http://127.0.0.1:8080/hello, user=root, password=123]
**************
sql3
2013年7月15日
新聞內容3
驗證1
**************
sql2
2013年7月14日
新聞內容2

**************
sql1
2013年7月13日
新聞內容1
驗證1










發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章