看到別人有個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=女))
使用起來其實挺簡單的,因爲時間有限沒有去研究他的原理,如有知道的可以補充。還是建議大家多去了解技術的原理,因爲如今技術實現越來越簡單,但是大家也離原理越來越遠。