1. 技術目標
- 目標01:如何組裝xml的vo對象
- 目標02:ObjectMapper和XmlMapper類的熟練使用
- 目標03:POJO2XML
- 目標04:XML2POJO
2. 技術介紹
最近在公司做一個對接開發(fā)票系統(tǒng)的工作,工作也剛好一年了,原本以為會是一件很簡單的事情,更不會花費多久的時間,但是當我打開對接公司發(fā)的接口文檔,我的眼前感到了一陣困惑,怎么數(shù)據(jù)的傳輸都是XML的格式呢?之前我曾經(jīng)寫過一篇后臺數(shù)據(jù)傳輸-JSON,介紹了各種JSON數(shù)據(jù)格式的傳輸,而XML是進公司這么久以來,第一次接觸這樣的接口,只能說明我的水平太cai了!在網(wǎng)上搜索和很久,發(fā)現(xiàn)大多都是通過[DOM、SAX、DOM4J、JDOM、Xstream],自己也按照嘗試了多次,雖然可以實現(xiàn)數(shù)據(jù)的組轉,但是這也太kegndie了吧!幸好在公司認識一個馬哥的同事,在他的指點下,完成了第一個demo的實現(xiàn),今天閑來無事,在此和大家分享一下,愿共同進步!話不多說,直接開始上代碼了。
3. 環(huán)境配置
3.1 開發(fā)配置
- JDK 1.8 或更高版本
- Maven 3 或更高版本
- MySQL Server 5.6
3.2 技術棧
- Spring Boot
- Jackson XML annotations
- MySQL
4. 技術實踐
4.1 創(chuàng)建項目
4.2 創(chuàng)建結構
4.2.1 pom.xml引入依賴
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
4.2.2 屬性文件配置
4.3 主要代碼
4.3.1 XML數(shù)據(jù)格式
<?xml version='1.0' encoding='UTF-8'?>
<root>
<header/>
<body id="1" size="2">
<datas>
<data k6="22">
<k1>k1</k1>
<k3>
<ki>1</ki>
<ki>2</ki>
</k3>
<k5>1</k5>
<k5>2</k5>
<k7>a7b</k7>
<k8>
<a>a7b</a>
</k8>
<k9>
<![CDATA[java]]>
</k9>
<k2>12</k2>
<k4>
<ka>1</ka>
<ka>2</ka>
</k4>
</data>
<data>
<k1/>
<k5/>
<k7/>
<k8/>
<k9/>
<k2/>
</data>
</datas>
</body>
</root>
4.3.2 創(chuàng)建VO對象
package cn.hacz.edu.vo;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
@JacksonXmlRootElement(localName = "root")
public class Root {
private Header header;
private Body body;
public Header getHeader() {
return header;
}
public void setHeader(Header header) {
this.header = header;
}
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
}
package cn.hacz.edu.vo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Header {
}
package cn.hacz.edu.vo;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Body {
@JacksonXmlProperty(isAttribute = true, localName = "id")
private String id;
@JacksonXmlProperty(isAttribute = true, localName = "size")
private Integer size;
/**
* List集合形式
*/
@JacksonXmlElementWrapper(localName = "datas")
@JacksonXmlProperty(localName = "data")
private List<Data> datas;
public List<Data> getDatas() {
return datas;
}
public void setDatas(List<Data> datas) {
this.datas = datas;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getSize() {
return getDatas().size();
}
public void setSize(Integer size) {
this.size = size;
}
}
package cn.hacz.edu.vo;
import java.util.Collection;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Data {
private String k1;
@JacksonXmlProperty(localName = "k2")
private Integer k2;
@JacksonXmlElementWrapper(localName = "k3")
private Collection<String> ki;
@JacksonXmlElementWrapper(localName = "k4")
@JacksonXmlProperty(localName = "ka")
private Collection<String> k4;
@JacksonXmlElementWrapper(localName = "k5", useWrapping = false)
private Collection<String> k5;
@JacksonXmlProperty(isAttribute = true)
private Integer k6;
private DataValue01 k7;
private DataValue02 k8;
// 序列化時是否總是使用 CDATA 塊
@JacksonXmlCData(value = true)
private String k9;
public String getK1() {
return k1;
}
public void setK1(String k1) {
this.k1 = k1;
}
public Integer getK2() {
return k2;
}
public void setK2(Integer k2) {
this.k2 = k2;
}
public Collection<String> getKi() {
return ki;
}
public void setKi(Collection<String> ki) {
this.ki = ki;
}
public Collection<String> getK4() {
return k4;
}
public void setK4(Collection<String> k4) {
this.k4 = k4;
}
public Collection<String> getK5() {
return k5;
}
public void setK5(Collection<String> k5) {
this.k5 = k5;
}
public Integer getK6() {
return k6;
}
public void setK6(Integer k6) {
this.k6 = k6;
}
public DataValue01 getK7() {
return k7;
}
public void setK7(DataValue01 k7) {
this.k7 = k7;
}
public DataValue02 getK8() {
return k8;
}
public void setK8(DataValue02 k8) {
this.k8 = k8;
}
public String getK9() {
return k9;
}
public void setK9(String k9) {
this.k9 = k9;
}
}
package cn.hacz.edu.vo;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
public class DataValue01 {
@JacksonXmlText
private String a;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
package cn.hacz.edu.vo;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
public class DataValue02 {
@JacksonXmlText(value = false)
private String a;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
4.3.3 ObjectMapper和XmlMapper
public static XmlMapper getxmlMapper() {
// 重要:創(chuàng)建XmlMapper; 它將使用適當?shù)墓S,解決方法。
XmlMapper xmlMapper = new XmlMapper();
// 格式化代碼
xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
// <?xml version='1.0' encoding='UTF-8'?>
xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
return xmlMapper;
}
4.3.4 POJO2XML
String writeValueAsString = getxmlMapper().writeValueAsString(root);
System.out.println(writeValueAsString);
4.3.5 XML2POJO
File file = new File("D:\\1.xml");
// 02、XML文件轉成POJO對象
Root readValue = getxmlMapper().readValue(file, Root.class);
List<Data> datas2 = readValue.getBody().getDatas();
for (Data data : datas2) {
System.out.println(data.getKi());
}
解析xml按照一定順序:@JsonPropertyOrder({"classStr","size"})
5. 技術總結
5.1
6. 代碼下載
本章以及后續(xù)章節(jié)的源碼地址我都會分享出來,請大家自行下載以及git clone。
SpringBoot相關系列文章請訪問:目錄:SpringBoot學習目錄