XStream是一個實現(xiàn)javaBean與XML互相轉換的工具沃但,極大地簡化了開發(fā)人員的對XML的處理
1鹏控、添加依賴
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11.1</version>
</dependency>
2利诺、UML類圖
<Document TaskGuid="560eec8a-be14-4398-8c9a-73b68651a129" DataGuid="" DataType=" QueryJYYKTByHourList" >
<Data>
<KBH Type="TEXT">卡編號</KBH>
<DEALRQ Type="TEXT">刷卡日期</DEALRQ>
<DEALSJ Type="TEXT">刷卡時間</DEALSJ>
<XLBM Type="TEXT">線路編碼</XLBM>
</Data>
<Data>
<KBH Type="TEXT">卡編號</KBH>
<DEALRQ Type="TEXT">刷卡日期</DEALRQ>
<DEALSJ Type="TEXT">刷卡時間</DEALSJ>
<XLBM Type="TEXT">線路編碼</XLBM>
</Data>
…數(shù)據(jù)重復出現(xiàn)
</Document>
假設現(xiàn)在需要將上面的xml轉換為一個JavaBean,那么首先需要分析這個XML的結構训挡,根節(jié)點是Document澳骤,有三個屬性TaskGuid、DataGuid舍哄、DataType宴凉,有許多個子節(jié)點Data誊锭,每個Data節(jié)點都有四個子節(jié)點:KBH表悬、DEALRQ、DEALSJ丧靡、XLBM蟆沫。可以采用這種思路:用一個Document類:有四個字段温治,TaskGuid饭庞、DataGuid、DataType與一個Data的集合熬荆。每一個Data都有四個字段:KBH舟山、DEALRQ、DEALSJ卤恳、XLBM累盗,每個字段都有一個Type和一個值。
UML類圖如下:
Document和Data是聚合關系突琳,Data脫離了Document可以獨立存在若债,Data和Kbh、Dealrq拆融、Dealsj與Xlbm是組合關系蠢琳,這四個脫離了Data就不能獨立存在。
3镜豹、XStream注解
主要使用
@XStreamAlias(“alis”)
java對象在xml中以標簽的形式顯示時傲须,如果名字與類名或者屬性名不一致,可以使用該標簽并在括號內(nèi)注明別名趟脂。
@XStreamOmitField
在輸出XML的時候忽略該屬性
@XStreamImplicit
如果該屬性是一個列表或者數(shù)組躏碳,在XML中不顯示list或者Array字樣
@XStreamAsAttribute
該屬性不單獨顯示成XML節(jié)點,而是作為屬性顯示出來
@XStreamConverter
設置轉換器
@XStreamConverters
converter主要用于將某些字段進行復雜的轉換散怖,轉換過程寫在一個類中菇绵。
然后將其注冊到XStream。
工具類:
public class XsteamUtil {
public static Object toBean(Class<?> clazz, String xml) {
Object xmlObject = null;
XStream xstream = new XStream();
xstream.processAnnotations(clazz);
xstream.autodetectAnnotations(true);
xmlObject= xstream.fromXML(xml);
return xmlObject;
}
}
在SpringBoot中可以使用@Bean來進行IOC镇眷,設置xstream.autodetectAnnotations(true);來處理注解
如果要進行xml轉JavaBean的操作咬最,需要設施xstream.alias()
4、具體使用
ReturnResult.java
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@ToString
@Accessors(chain = true)
@XStreamAlias("Document")
public class ReturnResult {
@XStreamAlias("TaskGuid")
@XStreamAsAttribute
private String taskGuid;
@XStreamAlias("DataGuid")
@XStreamAsAttribute
private String dataGuid;
@XStreamAlias("DataType")
@XStreamAsAttribute
private String dataType;
@XStreamImplicit
private List<Record> records;
}
使用了@XStreamAlias
注解給類與字段起別名欠动,ReturnResult
就對應根節(jié)點Document
永乌,Java代碼中變量名提倡使用小寫駝峰命名惑申,所以我對字段也使用的別名。@XStreamAsAttribute
不將字段作為節(jié)點來對待而是作為屬性翅雏。 @XStreamImplicit
不顯示最外層的集合的根節(jié)點圈驼。
Record.java
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@XStreamAlias("Data")
public class Record {
@XStreamAlias("KBH")
private CardNo cardNo;
@XStreamAlias("DEALRQ")
private DealDate dealDate;
@XStreamAlias("DEALSJ")
private DealTime dealTime;
@XStreamAlias("XLBM")
private RouteCode routeCode;
}
由于XML文件的節(jié)點名不夠見名知意,所以我使用@XStreamAlias
的方式來解決望几。
CardNo.java
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author huwen
* 卡編號
*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
@XStreamAlias("KBH")
@XStreamConverter(value= ToAttributedValueConverter.class, strings={"value"})
public class CardNo {
@XStreamAlias("Type")
private String type;
private String value;
}
一個<KBH Type="TEXT">卡編號</KBH>
節(jié)點既有屬性又有值绩脆,所以使用了@XStreamConverter
,用xstream自帶的轉換器進行轉換橄抹。
@Test
public void testReturnResult2(){
XStream xStream = new XStream();
//由于使用的注解靴迫,將自動檢測注解開啟
xStream.autodetectAnnotations(true);
List<Record> records = new ArrayList<>();
//設置對象的屬性值
CardNo k1 = new CardNo().setType("TEXT").setValue("36283723");
CardNo k2 = new CardNo().setType("TEXT").setValue("121211");
DealTime dealTime1 = new DealTime().setType("TEXT").setValue("12");
DealTime dealTime2 = new DealTime().setType("TEXT").setValue("1");
DealDate dealDate1 = new DealDate().setType("TEXT").setValue("20200617");
DealDate dealDate2 = new DealDate().setType("TEXT").setValue("20200520");
RouteCode routeCode1 = new RouteCode().setType("TEXT").setValue("212");
RouteCode routeCode2 = new RouteCode().setType("TEXT").setValue("112");
records.add(new Record().setCardNo(k1).setDealDate(dealDate1).setDealTime(dealTime1).setRouteCode(routeCode1));
records.add(new Record().setCardNo(k2).setDealDate(dealDate2).setDealTime(dealTime2).setRouteCode(routeCode2));
ReturnResult result = new ReturnResult().setDataType("QueryJYYKTByHourList").setTaskGuid("560eec8a-be14-4398-8c9a-73b68651a129")
.setDataGuid("d78whe28eh").setRecords(records);
//轉換為xml格式的字符串
String s = xStream.toXML(result);
String s1 =
"<Document TaskGuid=\"560eec8a-be14-4398-8c9a-73b68651a129\" DataGuid=\"d78whe28eh\" DataType=\"QueryJYYKTByHourList\">\n" +
" <Data>\n" +
" <KBH Type=\"TEXT\">36283723</KBH>\n" +
" <DEALRQ Type=\"TEXT\">20200617</DEALRQ>\n" +
" <DEALSJ Type=\"TEXT\">12</DEALSJ>\n" +
" <XLBM Type=\"TEXT\">212</XLBM>\n" +
" </Data>\n" +
" <Data>\n" +
" <KBH Type=\"TEXT\">121211</KBH>\n" +
" <DEALRQ Type=\"TEXT\">20200520</DEALRQ>\n" +
" <DEALSJ Type=\"TEXT\">1</DEALSJ>\n" +
" <XLBM Type=\"TEXT\">112</XLBM>\n" +
" </Data>\n" +
"</Document>";
System.out.println(s);
System.out.println(xStream.fromXML(s1));
}
上面的例子將JavaBean轉換為xml。
@Test
public void testReturnData(){
XStream xStream = new XStream();
xStream.autodetectAnnotations(true);
//必須要加這行代碼楼誓,否則會報錯玉锌,找不到這個類
xStream.alias("Document",ReturnResult.class);
String s = "<Document TaskGuid=\"560eec8a-be14-4398-8c9a-73b68651a129\" DataGuid=\"dhshdisds89e\" DataType=\"QueryJYYKTByHourList\">\n" +
" <Data>\n" +
" <KBH Type=\"TEXT\">12121</KBH>\n" +
" <DEALRQ Type=\"TEXT\">2020212</DEALRQ>\n" +
" <DEALSJ Type=\"TEXT\">12</DEALSJ>\n" +
" <XLBM Type=\"TEXT\">12</XLBM>\n" +
" </Data>\n" +
" <Data>\n" +
" <KBH Type=\"TEXT\">37612</KBH>\n" +
" <DEALRQ Type=\"TEXT\">2020312</DEALRQ>\n" +
" <DEALSJ Type=\"TEXT\">15</DEALSJ>\n" +
" <XLBM Type=\"TEXT\">23</XLBM>\n" +
" </Data>\n" +
"</Document>";
System.out.println(xStream.fromXML(s));
}
上面的例子將xml形式的字符串轉換為JavaBean,需要注意的是必須要加xStream.alias("Document",ReturnResult.class);這行代碼疟羹,否則會報com.thoughtworks.xstream.mapper.CannotResolveClassException: Document這個異常主守。
可以看出使用XStream的一般步驟:
- 創(chuàng)建XStream對象:XStream xStream = new XStream();
- 開始自動檢測注解:xStream.autodetectAnnotations(true);
- 進行轉換:fromXML或者toXML
既讓這個XStrem對象經(jīng)常使用,那么在Spring項目中可以使用Spring IOC將它交給Spring容器進行管理榄融,在需要的時候進行注入即可参淫。