java實體類和xml之間的轉換
XStream是一個Java物件和XML相互轉換的工具,很好很強大。提供了所有的基礎型別、陣列、集合等型別直接轉換的支援。
因此XML常用於資料交換、物件序列化(這種序列化和Java物件的序列化技術有著本質的區別)。
Stream物件相當Java物件和XML之間的轉換器,轉換過程是雙向的。建立XSteam物件的方式很簡單,只需要new XStream()即
可。
Java到xml,用toXML()方法。
Xml到Java,用fromXML()方法。
二、
在沒有任何設定預設情況下,java到xml的對映,是java成員名對應xml的元素名,java類的全名對應xml根元素的名字。而實際中,往
往是xml和java類都有了,要完成相互轉換,必須進行別名對映。
別名配置包含三種情況:
1、類別名,用alias(String name, Class type)。
2、類成員別名,用aliasField(String alias, Class definedIn, String fieldName)
3、類成員作為屬性別名,用 aliasAttribute(Class definedIn, String attributeName, String alias),單獨命名沒有意義,還要通過
useAttributeFor(Class definedIn, String fieldName) 應用到某個類上。
別名的配置是非常重要的,但是其中有些細節問題很重要,在例子中會專門做詳細說明。
另外還有不太常用的方法:
addImplicitCollection(Class ownerType, String fieldName),去掉集合型別生成xml的父節點。
registerConverter(Converter converter) ,註冊一個轉換器。
三、
如果這些基本的操作還不能滿足你應用的需求,XStream提供豐富的擴充套件點。你可以實現自己的轉換器。還可以利用XStream完成更負責的功能,比如輸出其他非xml格式的資料,還可以輸出html,還支援XML Dom型別資料,這些應用起來稍微複雜些。當然這些不是XStream應用的重點,也不用理會,真正需要的時候再檢視API和原始碼研究研究。
XStream的優點很多,但是也有一些小bug,比如在定義別名中的下劃線“_”轉換為xml後會變成“__”這個符號,很變態。因此,儘量避免在別名中實用任何符號,卻是需要下劃線的時候,可以考慮實用連線符“-”,這個沒有問題。
另外,我們的Java Bean中,常常有一些常量,在轉換過程,XStream也會將這些常量轉換過去,形成常量的xml節點,這顯然不是想要的結果,對於常量欄位,就不做轉換了。
四、
簡單例子:
package test;
import java.util.List;
public class Person {
private String name;
private String age;
private Profile profile;
private List<Address> addlist;
public Person(String name, String age, Profile profile,
List<Address> addlist) {
this.name = name;
this.age = age;
this.profile = profile;
this.addlist = addlist;
}
public Person(){
}
public String toString() {
return “Person{” + “name=’” + name + ‘\” + “, age=’” + age + ‘\”
+ “, profile=” + profile + “, addlist=” + addlist + ‘}’;
}
}
//=======================================================
package test;
public class Address {
private String add;
private String zipcode;
public Address(String add, String zipcode) {
this.add = add;
this.zipcode = zipcode;
}
public String toString() {
return “Address{” + “add=’” + add + ‘\” + “, zipcode=’” + zipcode
+ ‘\” + ‘}’;
}
}
//======================================================
package test;
public class Profile {
private String job;
private String tel;
private String remark;
public Profile(String job, String tel, String remark) {
this.job = job;
this.tel = tel;
this.remark = remark;
}
public String toString() {
return “Profile{” + “job=’” + job + ‘\” + “, tel=’” + tel + ‘\”
+ “, remark=’” + remark + ‘\” + ‘}’;
}
}
//==========================================================
package test;
import java.util.ArrayList;
import java.util.List;
import com.thoughtworks.xstream.XStream;
public class XStreamTest {
public static void main(String args[]) {
test();
}
public static void test() {
System.out
.println(“———-XStream學習:http://lavasoft.blog.51cto.com———-“);
// 目標物件
Address address1 = new Address(“鄭州市經三路”, “450001”);
Address address2 = new Address(“西安市雁塔路”, “710002”);
List<Address> addList = new ArrayList<Address>();
addList.add(address1);
addList.add(address2);
Profile profile = new Profile(“軟體工程師”, “13512129933”, “備註說明”);
Person person = new Person(“熔岩”, “27”, profile, addList);
// 轉換裝配
XStream xStream = new XStream();
output(0, xStream, person);
/************** 設定類別名 ****************/
xStream.alias(“PERSON”, test.Person.class);
xStream.alias(“PROFILE”, test.Profile.class);
xStream.alias(“ADDRESS”, test.Address.class);
output(1, xStream, person);
/************* 設定類成員的別名 ***************/
// 設定Person類的name成員別名Name
xStream.aliasField(“Name”, Person.class, “name”);
/*
* [注意] 設定Person類的profile成員別名PROFILE,這個別名和Profile類的別名一致,
* 這樣可以保持XStream物件可以從profile成員生成的xml片段直接轉換為Profile成員,
* 如果成員profile的別名和Profile的別名不一致,則profile成員生成的xml片段不可
* 直接轉換為Profile物件,需要重新建立XStream物件,這豈不給自己找麻煩?
*/
xStream.aliasField(“PROFILE”, test.Person.class, “profile”);
xStream.aliasField(“ADDLIST”, test.Person.class, “addlist”);
xStream.aliasField(“Add”, test.Address.class, “add”);
xStream.aliasField(“Job”, test.Profile.class, “job”);
output(2, xStream, person);
/******* 設定類成員為xml一個元素上的屬性 *******/
xStream.useAttributeFor(Address.class, “zipcode”);
output(3, xStream, person);
/************* 設定屬性的別名 ***************/
xStream.aliasAttribute(Address.class, “zipcode”, “Zipcode”);
output(4, xStream, person);
/************* 將xml轉為java物件 ******× ****/
String person_xml = “<PERSON>\n” + “ <Name>熔岩</Name>\n”
+ “ <age>27</age>\n” + “ <PROFILE>\n”
+ “ <Job>軟體工程師</Job>\n” + “ <tel>13512129933</tel>\n”
+ “ <remark>備註說明</remark>\n” + “ </PROFILE>\n”
+ “ <ADDLIST>\n” + “ <ADDRESS Zipcode=\”450001\”>\n”
+ “ <Add>鄭州市經三路</Add>\n” + “ </ADDRESS>\n”
+ “ <ADDRESS Zipcode=\”710002\”>\n”
+ “ <Add>西安市雁塔路</Add>\n” + “ </ADDRESS>\n”
+ “ </ADDLIST>\n” + “</PERSON>”;
String profile_xml = “ <PROFILE>\n” + “ <Job>軟體工程師</Job>\n”
+ “ <tel>13512129933</tel>\n”
+ “ <remark>備註說明</remark>\n” + “ </PROFILE>”;
String address_xml = “ <ADDRESS Zipcode=\”710002\”>\n”
+ “ <Add>西安市雁塔路</Add>\n” + “ </ADDRESS>”;
// 同樣實用上面的XStream物件xStream
System.out.println(xStream.fromXML(person_xml).toString());
System.out.println(xStream.fromXML(profile_xml).toString());
System.out.println(xStream.fromXML(address_xml).toString());
}
public static void output(int i, XStream xStream, Object obj) {
String xml = xStream.toXML(obj);
System.out.println(“>>>第[ ” + i + “]次輸出\n”);
System.out.println(xml + “\n”);
}
}
//=======================================================
———-XStream學習:http://lavasoft.blog.51cto.com———-
>>>第[ 0]次輸出
<test.Person>
<name>熔岩</name>
<age>27</age>
<profile>
<job>軟體工程師</job>
<tel>13512129933</tel>
<remark>備註說明</remark>
</profile>
<addlist>
<test.Address>
<add>鄭州市經三路</add>
<zipcode>450001</zipcode>
</test.Address>
<test.Address>
<add>西安市雁塔路</add>
<zipcode>710002</zipcode>
</test.Address>
</addlist>
</test.Person>
>>>第[ 1]次輸出
<PERSON>
<name>熔岩</name>
<age>27</age>
<profile>
<job>軟體工程師</job>
<tel>13512129933</tel>
<remark>備註說明</remark>
</profile>
<addlist>
<ADDRESS>
<add>鄭州市經三路</add>
<zipcode>450001</zipcode>
</ADDRESS>
<ADDRESS>
<add>西安市雁塔路</add>
<zipcode>710002</zipcode>
</ADDRESS>
</addlist>
</PERSON>
>>>第[ 2]次輸出
<PERSON>
<Name>熔岩</Name>
<age>27</age>
<PROFILE>
<Job>軟體工程師</Job>
<tel>13512129933</tel>
<remark>備註說明</remark>
</PROFILE>
<ADDLIST>
<ADDRESS>
<Add>鄭州市經三路</Add>
<zipcode>450001</zipcode>
</ADDRESS>
<ADDRESS>
<Add>西安市雁塔路</Add>
<zipcode>710002</zipcode>
</ADDRESS>
</ADDLIST>
</PERSON>
>>>第[ 3]次輸出
<PERSON>
<Name>熔岩</Name>
<age>27</age>
<PROFILE>
<Job>軟體工程師</Job>
<tel>13512129933</tel>
<remark>備註說明</remark>
</PROFILE>
<ADDLIST>
<ADDRESS zipcode=”450001”>
<Add>鄭州市經三路</Add>
</ADDRESS>
<ADDRESS zipcode=”710002”>
<Add>西安市雁塔路</Add>
</ADDRESS>
</ADDLIST>
</PERSON>
>>>第[ 4]次輸出
<PERSON>
<Name>熔岩</Name>
<age>27</age>
<PROFILE>
<Job>軟體工程師</Job>
<tel>13512129933</tel>
<remark>備註說明</remark>
</PROFILE>
<ADDLIST>
<ADDRESS Zipcode=”450001”>
<Add>鄭州市經三路</Add>
</ADDRESS>
<ADDRESS Zipcode=”710002”>
<Add>西安市雁塔路</Add>
</ADDRESS>
</ADDLIST>
</PERSON>