Java對象表示方式2:XStream實現對對象的XML化


前言

上一篇文章講到了使用Java原生的序列化的方式來表示一個對象。總結一下這種對象表示方式的優缺點:

1、純粹的Java環境下這種方式可以很好地工作,因為它是Java自帶的,也不需要第三方的Jar包的支持

2、多語言環境下,使用Java序列化方式進行存儲后,很難用其他語言還原出結果

3、占用的字節數比較大,而且序列化、反序列化效率也不高

前面也提到過,對象表示有各種各樣的方式,序列化只是其中的一種而已。表示一個對象的目的無非就是為了對象<---->IO之間相互認識,至於怎么認識,那就有很多選擇了。除了之前講過的序列化,還可以選擇將數據JSON化、XML化。當前也有比較好用的序列化工具,比如Google的protobuf。這篇文章主要想寫一下對對象進行XML化,使用的是XStream。至於為什么選擇寫XStream,因為工作用,呵呵。

 

利用XStream表示一個對象

XStream就是一種Java對象和XML之間相互轉換的工具,沒有什么可以特別介紹的,XStream提供了所有的基礎類型、數組、集合等類型直接轉換的支持。XStream中的核心類就是XStream類,一般來說熟悉這個類就夠用了。使用XStream需要用到兩個第三方jar包,我工程里面使用的xstream-1.4.jarkxml2.jar。一開始我在玩XStream以為只需要前一個jar包就可以了,結果運行的時候各種錯誤,所以這里要注意一下。首先寫一個最簡單的程序:

 1 public class XmlObject
 2 {
 3     private int       count;
 4     private double    price;
 5     private String    phone;
 6     
 7     public XmlObject(int count, double price, String phone)
 8     {
 9         this.count = count;
10         this.price = price;
11         this.phone = phone;
12     }
13 
14     public String toString()
15     {
16         return "count = " + count + ", price = " + price + ", phone = " + phone;
17     }
18 }
1 public static void main(String[] args)
2 {
3     XStream xs = new XStream();
4     XmlObject xo = new XmlObject(10, 10.5, "110");
5     String str = xs.toXML(xo);
6     System.out.println(str);
7 }

看一下運行結果:

<com.xrq.test.XmlObject>
  <count>10</count>
  <price>10.5</price>
  <phone>110</phone>
</com.xrq.test.XmlObject>

是的,這么簡單,就把一個對象表示出來了。這時候,想怎么操作這個str都無所謂了,可以用一個FileWriter把這個str存入磁盤,也可以用一個HttpClient傳輸這串str進行網絡通信。

 

設置一下別名

OK,看到上面這串輸出,可能有些人不爽了,“com.xrq.test.XmlObject”這么麻煩,能不能表示地簡單點啊?當然可以,而且不僅可以對對象重命名,對象中的屬性也可以:

 1 public static void main(String[] args)
 2 {
 3     XStream xs = new XStream();
 4     XmlObject xo = new XmlObject(10, 10.5, "110");
 5     xs.alias("XmlObject", XmlObject.class);
 6     xs.aliasField("Count", XmlObject.class, "count");
 7     xs.aliasField("Price", XmlObject.class, "price");
 8     xs.aliasField("Phone", XmlObject.class, "phone");
 9     String str = xs.toXML(xo);
10     System.out.println(str);
11 }

看一下運行結果:

<XmlObject>
  <Count>10</Count>
  <Price>10.5</Price>
  <Phone>110</Phone>
</XmlObject>

看到,對象名變了,對象中的屬性名也變化了。

 

XStream支持數組和集合

之前說過,XStream不僅支持基本數據類型,也支持數組、集合,把程序修改一下再看一下:

 1 public class XmlObject
 2 {
 3     private int[]                 counts;
 4     private List<String>          phones;
 5     private Map<String, Date>     calendar;
 6     
 7     public XmlObject(int[] counts, List<String> phones, Map<String, Date> calendar)
 8     {
 9         this.counts = counts;
10         this.phones = phones;
11         this.calendar = calendar;
12     }
13 
14     public String toString()
15     {
16         return "count = " + counts + ", phones = " + phones + ", calendar = " + calendar;
17     }
18 }
 1 public static void main(String[] args)
 2 {
 3     int[] counts = {10, 11, 12};
 4     List<String> phones = new ArrayList<String>();
 5     phones.add("110");
 6     phones.add("119");
 7     phones.add("120");
 8     Map<String, Date> calendar = new HashMap<String, Date>();
 9     calendar.put("1", new Date());
10     calendar.put("2", new Date());
11     XStream xs = new XStream();
12     XmlObject xo = new XmlObject(counts, phones, calendar);
13     xs.alias("XmlObject", XmlObject.class);
14     xs.aliasField("Count", XmlObject.class, "counts");
15     xs.aliasField("Phones", XmlObject.class, "phones");
16     xs.aliasField("Calendar", XmlObject.class, "calendar");
17     String str = xs.toXML(xo);
18     System.out.println(str);
19 }

看一下運行結果

<XmlObject>
  <Count>
    <int>10</int>
    <int>11</int>
    <int>12</int>
  </Count>
  <Phones>
    <string>110</string>
    <string>119</string>
    <string>120</string>
  </Phones>
  <Calendar>
    <entry>
      <string>2</string>
      <date>2015-09-20 08:23:13.665 UTC</date>
    </entry>
    <entry>
      <string>1</string>
      <date>2015-09-20 08:23:13.665 UTC</date>
    </entry>
  </Calendar>
</XmlObject>

看到string、date這兩個開頭字母都是小寫的有點不爽?沒關系,依樣畫葫蘆,main函數里面加上這兩句就可以了

xs.alias("String", String.class);
xs.alias("Date", Date.class);

 

XML轉換成Java對象

回歸前面最簡單的那個XmlObject,看一下把XML轉換為Java對象,也很簡單,利用fromXml()方法就可以了。自己構造一個xml字符串:

1 public static void main(String[] args)
2 {
3     XStream xs = new XStream();
4     String xmlStr = "<com.xrq.test.XmlObject><count>10</count><price>10.5</price><phone>110</phone></com.xrq.test.XmlObject>";
5     XmlObject xo = (XmlObject)xs.fromXML(xmlStr);
6     System.out.println(xo);
7 }

運行結果就不貼了,就是XmlObject三個屬性的toString()而已。注意這里用的沒有alias過的“com.xrq.test.XmlObject”,要是直接用“XmlObject”會報“com.thoughtworks.xstream.mapper.CannotResolveClassException”這個異常。解決方案很簡單,第5行前面加上xs.alias("XmlObject", XmlObject.class);就好了。

 

后記

文章主要寫了對於XStream的使用,一般來說,XStream用到這個程度也就夠了。XStream使用非常容易,而且XML化之后的數據可讀性強。不過在github上看到了一篇文章https://github.com/eishay/jvm-serializers/wiki,看得出XML的缺點主要在於還是解析的時候效率低了一些,而且為了可讀性,XML也引入了一些冗余的文本信息從而造成了一定的空間開銷。但是,無論如何,操作量不大的場景下 ,個人還是推薦使用XStream。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM