使用JAXB包實(shí)現(xiàn)bean和xml的互轉(zhuǎn)
前言
由于項(xiàng)目需要,調(diào)用第三方接口,接口返回格式為xml格式。遂用上了javax.xml 用于實(shí)現(xiàn)Bean和xml互轉(zhuǎn)
首先我們看看工具類XmlUtil
/**
* XML轉(zhuǎn)對(duì)象
*
* @param xmlStr xml字串
* @param t 對(duì)象類型
* @return 對(duì)象
*/
public static <T> T xmlToBean(String xmlStr, Class<T> t) {
try {
//特殊字符不讓其轉(zhuǎn)義,不然會(huì)報(bào)錯(cuò)
if (xmlStr.contains("")) {
xmlStr = xmlStr.replace("","<![CDATA[]]>");
}
JAXBContext context = JAXBContext.newInstance(t);
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader reader = new StringReader(xmlStr);
SAXParserFactory sax = SAXParserFactory.newInstance();
//設(shè)置忽略命名空間
sax.setNamespaceAware(false);
XMLReader xmlReader = sax.newSAXParser().getXMLReader();
Source source = new SAXSource(xmlReader, new InputSource(reader));
return (T) unmarshaller.unmarshal(source);
} catch (JAXBException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
return null;
}
/**
* 對(duì)象轉(zhuǎn)XML
*
* @param obj 對(duì)象
* @return 字符串
*/
public static String beanToXml(Object obj) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
// marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
marshaller.marshal(obj, out);
try {
return new String(out.toByteArray(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} catch (JAXBException e) {
e.printStackTrace();
}
return null;
}
代碼解釋
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
如果為true的話,則不會(huì)生成<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
使用的Bean
@XmlRootElement(name = "requestXML")
@XmlAccessorType(XmlAccessType.FIELD)
public class TelefenCommonVO {
/**
* 應(yīng)用編碼
*/
@XmlElement(name = "AppID")
private String appid;
/**
* 接入業(yè)務(wù)
*/
private String SPID;
/**
* 請(qǐng)求流水
*/
private String RequestNo;
/**
* 請(qǐng)求時(shí)間
*/
private String RequestTime;
/**
* 簽名
*/
@XmlTransient
private String Sign;
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getSPID() {
return SPID;
}
public void setSPID(String SPID) {
this.SPID = SPID;
}
public String getRequestNo() {
return RequestNo;
}
public void setRequestNo(String requestNo) {
RequestNo = requestNo;
}
public String getRequestTime() {
return RequestTime;
}
public void setRequestTime(String requestTime) {
RequestTime = requestTime;
}
public String getSign() {
return Sign;
}
public void setSign(String sign) {
this.Sign = sign;
}
public TelefenCommonVO() {
}
protected TelefenCommonVO(Builder builder) {
this.appid = builder.AppID;
this.SPID = builder.SPID;
this.RequestNo = builder.RequestNo;
this.RequestTime = builder.RequestTime;
this.Sign = builder.Sign;
}
public static final class Builder{
/**
* 應(yīng)用編碼
*/
private String AppID;
/**
* 接入業(yè)務(wù)
*/
private String SPID;
/**
* 請(qǐng)求流水
*/
private String RequestNo;
/**
* 請(qǐng)求時(shí)間
*/
private String RequestTime;
/**
* 簽名
*/
private String Sign;
public Builder setAppID(String appID) {
this.AppID = appID;
return this;
}
public Builder setSPID(String SPID){
this.SPID = SPID;
return this;
}
public Builder setRequestNo(String requestNo){
this.RequestNo = requestNo;
return this;
}
public Builder setRequestTime(String requestTime){
this.RequestTime = requestTime;
return this;
}
public Builder setSign(String sign){
this.Sign = sign;
return this;
}
public TelefenCommonVO build() {
return new TelefenCommonVO(this);
}
}
}
代碼解釋
@XmlRootElement(name = "requestXML") 注解是指定xml的根節(jié)點(diǎn),作用在類上
@XmlAccessorType 用于指定有java對(duì)象生成xml文件時(shí)對(duì)java對(duì)象屬性的訪問方式。 它的屬性值是XmlAccessType的四個(gè)枚舉值。分別是:
XmlAccessType.FIELD java 對(duì)象中的所有成員變量
XmlAccessType.PROPERTY java對(duì)象中所有通過(guò)getter/setter 方式訪問的成員變量。
XmlAccessType.PUBLIC_MEMBER java 對(duì)象中所有的public 訪問權(quán)限的成員變量和通過(guò)getter/setter方式訪問的成員變量 。
XmlAccessType.NONE java對(duì)象的所有屬性都不映射為XML元素
@XmlElement
該注解用在類的屬性上。用于將屬性映射為xml的子節(jié)點(diǎn),可通過(guò)在后面配置name屬性值類改變java屬性在xml文件中的名稱。例如:
@XmlElement(name = "AppID")
private String appid;
轉(zhuǎn)化成xml為<AppID></AppID> 而不是<appid></appid>
5. @XmlAccessorOrder
用于對(duì)java 對(duì)象生成的xml元素進(jìn)行排序。它有兩個(gè)屬性值:
AccessorOrder.ALPHABETICAL:對(duì)生成的xml元素按字母順序排序;
XmlAccessOrder.UNDEFINED:不進(jìn)行排序
6. @XmlTransient
用于標(biāo)示在由java對(duì)象映射xml時(shí),忽略此屬性。即,在生成的xml文件中不出現(xiàn)此元素。
7. @XmlElementWrapper
在注解最外面再加一層,可用于POJO中包含List的屬性中,例如:
待轉(zhuǎn)化sql
<responseXML>
<Details>
<Detail>
<CardNo>11111</CardNo>
<CardPwd>2222</CardPwd>
<CodeURL/>
</Detail>
</Details>
</responseXML>
對(duì)應(yīng)的Bean
@XmlRootElement(name ="responseXML")
@XmlAccessorType(XmlAccessType.FIELD)
public class OrderPayRespVO {
/**
* 卡信息列表
*/
@XmlElementWrapper(name="Details")
@XmlElement(name = "Detail")
private List<Detail> Details;
省略get,set方法
}
@XmlRootElement(name = "Detail")
@XmlAccessorType(XmlAccessType.FIELD)
public class Detail {
/**
* 卡號(hào)
*/
private String CardNo;
/**
* 卡密
*/
private String CardPwd;
/**
* 短鏈
*/
private String CodeURL;
省略get,set方法
}
轉(zhuǎn)化之后
OrderPayRespVO{Details=[Detail{CardNo='11111', CardPwd='2222', CodeURL=''}]}
此外該Bean 還使用到了建造者設(shè)計(jì)模式來(lái)實(shí)現(xiàn)屬性的鏈?zhǔn)秸{(diào)用。
測(cè)試代碼
public static void main(String[] args) throws IOException {
TelefenCommonVO commonVO = new TelefenCommonVO.Builder()
.setAppID("1112")
.setRequestNo("3333")
.setSPID("444")
.setRequestTime("20180823")
.setSign("qqwqwqwq1121")
.build();
String xml = beanToXml(commonVO);
System.out.println("返回的xml為="+xml);
TelefenCommonVO commonVO1 = xmlToBean(xml, TelefenCommonVO.class);
System.out.println("轉(zhuǎn)化后的bean為="+commonVO1.toString());
}
運(yùn)行結(jié)果
返回的xml為=<?xml version="1.0" encoding="UTF-8" standalone="yes"?><requestXML><AppID>1112</AppID><SPID>444</SPID><RequestNo>3333</RequestNo><RequestTime>20180823</RequestTime></requestXML>
轉(zhuǎn)化后的bean為=TelefenCommonVO{appid='1112', SPID='444', RequestNo='3333', RequestTime='20180823', Sign='null'}
作者:碼農(nóng)飛哥
微信公眾號(hào):碼農(nóng)飛哥