使用JAXB進行XML與JavaBean的轉換(支持泛型)

看到別人有個1024的勳章,特意留了一篇在今年的10.24日,看看會不會獲得。

在日常開發中可能涉及接口之間的相互調用,雖然在現在微服務的理念推廣下,很多公司都採用輕量級的JSON格式做爲序列化的格式,但是不乏有些公司還是有一些XML格式的報文,最近就在對接某個合作方的時候遇到了XML報文。在JSON報文爽快的轉換下很難試用一個一個的拿報文參數,還是希望能直接將報文轉換成Bean。接下來就瞭解到了一些插件,因爲代碼中使用了泛型,所以經過多方對比之後還是選擇了JAXB,接下來就介紹一下JAXB的使用。

1.創建兩個Bean來作爲轉換模版(使用泛型),@XmlRootElement(name = "GIRL") 用來對應報文的封裝節點;@XmlAccessorType(XmlAccessType.FIELD) 表示只將變量轉換爲實體,配合 @Data 使用爽得很。

package com.example.dragon.main.dao.model.xmlutil;

import lombok.Data;

import javax.xml.bind.annotation.*;
import java.util.List;

/**
 * @ClassNAME girl
 * @Description 女孩兒對象
 * @Author XiongMao
 * @Date 2019-9-8
 */
@Data
@XmlRootElement(name = "GIRL")
@XmlAccessorType(XmlAccessType.FIELD)
public class Girl<T> {
    @XmlElement(name = "NAME")
    private String name;
    /**
     * XmlAnyElement 這個註解可以去調生成的xml中帶的xsi:type等信息,使用這個註解就不能使用 @XmlElement,
     *  需要在泛型對應的實體上增加 @XmlRootElement 註解
     *  XmlElementWrapper 這個註解可以在集合外層包裝一個節點
     */
    @XmlAnyElement(lax = true)
    private T ageAndSex;
}
package com.example.dragon.main.dao.model.xmlutil;

import lombok.Data;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @ClassNAME AgeAndSex
 * @Description 年齡與性別對象
 * @Author XiongMao
 * @Date 2019-9-8
 */
@Data
@XmlRootElement(name="AGEANDSEX")
@XmlAccessorType(XmlAccessType.FIELD)
public class AgeAndSex {
    @XmlElement(name="AGE")
    private String age;
    @XmlElement(name="SEX")
    private String sex;
}

2.做一個工具類封裝轉換的代碼,代碼中都有註釋,其中借鑑了一些博客內容,時間久了忘記了,如有發現請告知:

package com.example.dragon.main.util;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * @ClassNAME XmlUtil
 * @Description XML與bean互相轉換
 * @Author XiongMao
 * @Date 2019-9-7
 */
public class XmlUtil {

    /**
     * @Description bean轉成xml
     * @Param [t]
     * @Return java.lang.String
     */
    public static <T> String beanToXml(T t) throws JAXBException {
        //獲得 JAXBContext 類的新實例。參數爲類的地址
        JAXBContext context = JAXBContext.newInstance(t.getClass());
        //創建一個可以用來將 java 內容樹轉換爲 XML 數據的 Marshaller 對象。
        Marshaller m = context.createMarshaller();
        //創建一個StringWriter流將接收到的對象流寫入xml字符串
        StringWriter sw = new StringWriter();
        //調用marshal方法進行轉換
        m.marshal(t,sw);
        //將讀取到的StringWriter流轉成String返回
        return sw.toString();
    }

    /**
     * @Description bean轉成xml(泛型使用)
     * @Param [t]
     * @Return java.lang.String
     */
    public static <T> String beanToXml(T t, Class c) throws JAXBException {
        //獲得 JAXBContext 類的新實例。參數爲類的地址
        JAXBContext context = JAXBContext.newInstance(t.getClass(),c);
        //創建一個可以用來將 java 內容樹轉換爲 XML 數據的 Marshaller 對象。
        Marshaller m = context.createMarshaller();
        //創建一個StringWriter流將接收到的對象流寫入xml字符串
        StringWriter sw = new StringWriter();
        //調用marshal方法進行轉換
        m.marshal(t,sw);
        //將讀取到的StringWriter流轉成String返回
        return sw.toString();
    }

    /**
     * @Description xml 轉成 bean
     * @Param [xml, t]
     * @Return T
     */
    public static <T> T xmlToBean(String xml, T t) throws JAXBException {
        ////獲得 JAXBContext 類的新實例。參數爲類的地址
        JAXBContext context = JAXBContext.newInstance(t.getClass());
        //創建一個可以用來將 XML 數據轉換爲 java 內容樹的 Unmarshaller 對象。
        Unmarshaller um = context.createUnmarshaller();
        //創建一個StringReader將xml報文轉成流
        StringReader sr = new StringReader(xml);
        //調用unmarshal進行轉換,並把Object類型強轉爲調用者的類型
        t = (T) um.unmarshal(sr);
        //將對象返回給調用者
        return t;
    }

    /**
     * @Description xml 轉成 bean(泛型使用)
     * @Param [xml, t]
     * @Return T
     */
    public static <T> T xmlToBean(String xml, T t, Class c) throws JAXBException {
        ////獲得 JAXBContext 類的新實例。參數爲類的地址
        JAXBContext context = JAXBContext.newInstance(t.getClass(),c);
        //創建一個可以用來將 XML 數據轉換爲 java 內容樹的 Unmarshaller 對象。
        Unmarshaller um = context.createUnmarshaller();
        //創建一個StringReader將xml報文轉成流
        StringReader sr = new StringReader(xml);
        //調用unmarshal進行轉換,並把Object類型強轉爲調用者的類型
        t = (T) um.unmarshal(sr);
        //將對象返回給調用者
        return t;
    }
}

3.接下來做一個main方法測試一下運行結果:

main方法:
        Girl girl = new Girl();
        girl.setName("小紅");
        AgeAndSex ageAndSex = new AgeAndSex();
        ageAndSex.setAge("18");
        ageAndSex.setSex("女");
        girl.setAgeAndSex(ageAndSex);
        System.out.println("組裝完成的對象值爲:" + girl);
        //方法調用並輸出
        Girl newGirl = new Girl();
        String xml;
        try {
            xml = XmlUtil.beanToXml(girl, AgeAndSex.class);
            System.out.println("bean轉成xml格式爲:" + xml);
            newGirl = XmlUtil.xmlToBean(xml, newGirl, AgeAndSex.class);
            System.out.println("xml轉成bean格式爲:" + newGirl);
        } catch (JAXBException e) {
            e.printStackTrace();
        }

結果:
    組裝完成的對象值爲:Girl(name=小紅, ageAndSex=AgeAndSex(age=18, sex=女))
    bean轉成xml格式爲:<?xml version="1.0" encoding="UTF-8" standalone="yes"?><GIRL><NAME>小    紅</NAME><AGEANDSEX><AGE>18</AGE><SEX>女</SEX></AGEANDSEX></GIRL>
    xml轉成bean格式爲:Girl(name=小紅, ageAndSex=AgeAndSex(age=18, sex=女))

使用起來其實挺簡單的,因爲時間有限沒有去研究他的原理,如有知道的可以補充。還是建議大家多去了解技術的原理,因爲如今技術實現越來越簡單,但是大家也離原理越來越遠。

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