• 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 }
    复制代码

    看一下运行结果

    看到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。

  • 相关阅读:
    String类的常用成员方法
    String类和StringBuffer类
    记事本
    GridLayout 可使容器中的各个组件呈网格状布局
    在使用add()方法添加组件到容器时,必须指定将其放置在哪个区域中
    每个容器都有一个布局管理器
    框架一般用作Java应用程序的窗口,而Applet是Java小程序的窗口
    面板是一种透明的容器,没有标题和边框
    要生成一个窗口,通常使用Window的子类Frame类进行实例化
    分布式系统 (大规模分布式系统原理解析和架构实践)
  • 原文地址:https://www.cnblogs.com/szlbm/p/5504169.html
Copyright © 2020-2023  润新知