研發(fā)過(guò)程中遇到的坑坑洼洼
很多時(shí)候我們不僅要解析json格式的數(shù)據(jù)声滥,xml也是一種很常見(jiàn)的數(shù)據(jù)格式眉撵,很多老的系統(tǒng)都采用的這種方式,我們要與之通訊和交換數(shù)據(jù)就必須做數(shù)據(jù)轉(zhuǎn)換落塑,XStream很方便的實(shí)現(xiàn)了bean和xml的互轉(zhuǎn)纽疟,而且性能非常優(yōu)越,應(yīng)該xml都會(huì)選擇XStream芜赌,雖然好用也會(huì)有一些小坑仰挣。
請(qǐng)看如下程序步驟
一、情況:通過(guò)XStream把xml數(shù)據(jù)轉(zhuǎn)換成Statusbox對(duì)象列表返回
XStream xstream = new XStream();
xstream.alias("returnsms", ArrayList.class);
xstream.alias("statusbox", Statusbox.class);//把XML解析為Statusbox對(duì)象返回
return (List<Statusbox>) xstream.fromXML(in);
二缠沈、在業(yè)務(wù)層調(diào)用的時(shí)候
List<Statusbox> statusboxList = shortMessage.getReport();
for (int i = 0; i < statusboxList.size(); i++) {
Statusbox statusbox = statusboxList.get(i); // 這里就報(bào)錯(cuò)了
}
Statusbox statusbox = statusboxList.get(i); // 這里就報(bào)錯(cuò)了看一下錯(cuò)誤
三、竟然報(bào)錯(cuò)了,看了錯(cuò)誤肯定會(huì)覺(jué)得很困惑
Caused by: java.lang.ClassCastException: com.project.tool.sms.Statusbox cannot be cast to com.project.tool.sms.Statusbox
1洲愤、com.project.tool.sms.Statusbox
2颓芭、com.project.tool.sms.Statusbox
兩個(gè)相同的類(lèi)既然不能轉(zhuǎn),在單獨(dú)的測(cè)試類(lèi)中測(cè)試也是沒(méi)問(wèn)題的柬赐,但是一發(fā)布到生產(chǎn)環(huán)境就報(bào)錯(cuò)亡问。這是為什么呢?
解決方法
原因我們運(yùn)用的是Springboot采用的類(lèi)加載器(ClassLoader)的同時(shí)肛宋,XStream也用在用自己的類(lèi)加載器州藕。當(dāng)兩個(gè)不同的ClassLoader對(duì)象加載具有相同名稱(chēng)的類(lèi)時(shí)(Java中兩個(gè)類(lèi)的相等性取決于加載它的完全名稱(chēng)和類(lèi)加載器)
因此,如果兩個(gè)獨(dú)立的類(lèi)加載器從同一位置加載類(lèi)酝陈,那么這些類(lèi)型的對(duì)象將無(wú)法轉(zhuǎn)換為彼此的類(lèi)型床玻。
XStream xstream = new XStream();
xstream.setClassLoader(getClass().getClassLoader());
xstream.alias("returnsms", ArrayList.class);
xstream.alias("statusbox", Statusbox.class);//把XML解析為Statusbox對(duì)象返回
return (List<Statusbox>) xstream.fromXML(in);
添加了一行 xstream.setClassLoader(getClass().getClassLoader());
讓XStream采用和Springboot同一個(gè)類(lèi)加載器即可。