android 中XML和对象转换利器Xstream的使用

XStream框架:

虽说pull dom dom4j等优秀的xml解析工具使用非常广泛,但对于复杂庞大的数据交互来说,使用它们无疑让你倍加痛苦,你可能大部分精力都放在无聊繁琐的解析和拼装上,如果接口稍微改动,更令你有股辞职不相干的冲动,或许你更倾向选择JSON,但有时候你还是不得不面对JSON,XML,对象之间的转化的烦恼,如何用最简单的办法一统混乱的局面,让你全心全意做设计写业务?现在有了XStream,一切将变得美好,永远告别原始手工作坊,让你轻松的享受coding带来的快乐

XStream可以轻易的将Java对象和xml文档相互转换,而且可以修改某个特定的属性和节点名称,而且也支持json的转换;

 json-lib这个框架 ,Jackson这个框架, 它们都完美支持JSON,但是对xml的支持还不是很好。一定程度上限制了对Java对象的描述,不能让xml完全体现到对Java对象的描述。这里将会介绍XStream对JSON、XML的完美支持。XStream不仅对XML的转换非常友好,而且提供annotation注解,可以在JavaBean中完成对xml节点、属性的描述。以及对JSON也支持,只需要提供相关的JSONDriver就可以完成转换。  


准备环境

首先去 Xstream官方网址 下载最新的jar包,此jar包可以再java和Android环境下都适用


测试用例代码

     
     
     
     
[java] view plain copy
  1. package com.hoo.test;  
  2.    
  3. import java.io.IOException;  
  4. import java.io.ObjectInputStream;  
  5. import java.io.ObjectOutputStream;  
  6. import java.io.StringReader;  
  7. import java.io.Writer;  
  8. import java.util.ArrayList;  
  9. import java.util.HashMap;  
  10. import java.util.Iterator;  
  11. import java.util.List;  
  12. import java.util.Map;  
  13. import java.util.Set;  
  14. import org.codehaus.jettison.json.JSONException;  
  15. import org.junit.After;  
  16. import org.junit.Before;  
  17. import org.junit.Test;  
  18. import com.hoo.entity.Birthday;  
  19. import com.hoo.entity.Classes;  
  20. import com.hoo.entity.ListBean;  
  21. import com.hoo.entity.Student;  
  22. import com.thoughtworks.xstream.XStream;  
  23. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;  
  24. import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;  
  25. import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;  
  26. import com.thoughtworks.xstream.io.json.JsonWriter;  
  27.    
  28. /** 
  29.  * function:Java对象和XML字符串的相互转换 
  30.  * jar-lib-version: xstream-1.3.1 
  31.  * @author hoojo 
  32.  * @createDate Nov 27, 2010 12:15:15 PM 
  33.  * @file XStreamTest.java 
  34.  * @package com.hoo.test 
  35.  * @project WebHttpUtils 
  36.  * @blog http://blog.csdn.net/IBM_hoojo 
  37.  * @email [email protected] 
  38.  * @version 1.0 
  39.  */  
  40. @SuppressWarnings("unchecked")  
  41. public class XStreamTest {  
  42.       
  43.     private XStream xstream = null;  
  44.     private ObjectOutputStream  out = null;  
  45.     private ObjectInputStream in = null;  
  46.       
  47.     private Student bean = null;  
  48.       
  49.     /** 
  50.      * function:初始化资源准备 
  51.      * @author hoojo 
  52.      * @createDate Nov 27, 2010 12:16:28 PM 
  53.      */  
  54.     @Before  
  55.     public void init() {  
  56.         try {  
  57.             xstream = new XStream();  
  58.             //xstream = new XStream(new DomDriver()); // 需要xpp3 jar  
  59.         } catch (Exception e) {  
  60.             e.printStackTrace();  
  61.         }  
  62.         bean = new Student();  
  63.         bean.setAddress("china");  
  64.         bean.setEmail("[email protected]");  
  65.         bean.setId(1);  
  66.         bean.setName("jack");  
  67.         Birthday day = new Birthday();  
  68.         day.setBirthday("2010-11-22");  
  69.         bean.setBirthday(day);  
  70.     }  
  71.       
  72.     /** 
  73.      * function:释放对象资源 
  74.      * @author hoojo 
  75.      * @createDate Nov 27, 2010 12:16:38 PM 
  76.      */  
  77.     @After  
  78.     public void destory() {  
  79.         xstream = null;  
  80.         bean = null;  
  81.         try {  
  82.             if (out != null) {  
  83.                 out.flush();  
  84.                 out.close();  
  85.             }  
  86.             if (in != null) {  
  87.                 in.close();  
  88.             }  
  89.         } catch (IOException e) {  
  90.             e.printStackTrace();  
  91.         }  
  92.         System.gc();  
  93.     }  
  94.       
  95.     public final void fail(String string) {  
  96.         System.out.println(string);  
  97.     }  
  98.       
  99.     public final void failRed(String string) {  
  100.         System.err.println(string);  
  101.     }  
  102. }  

通过XStream对象的toXML方法就可以完成Java对象到XML的转换,toXML方法还有2个相同签名的方法,需要传递一个流。然后通过流来完成xml信息的输出。

需要的JavaBean 

[java]  view plain  copy
  1. package com.hoo.entity;  
  2.    
  3. public class Student {  
  4.     private int id;  
  5.     private String name;  
  6.     private String email;  
  7.     private String address;  
  8.     private Birthday birthday;  
  9.     //getter、setter  
  10.     public String toString() {  
  11.         return this.name + "#" + this.id + "#" + this.address + "#" + this.birthday + "#" + this.email;  
  12.     }  
  13. }  


一、Java转换成XML

1、 JavaBean转换XM

     
     
     
     
[java] view plain copy
  1. /** 
  2.  * function:Java对象转换成XML字符串 
  3.  * @author hoojo 
  4.  * @createDate Nov 27, 2010 12:19:01 PM 
  5.  */  
  6. @Test  
  7. public void writeBean2XML() {  
  8.     try {  
  9.         fail("------------Bean->XML------------");  
  10.         fail(xstream.toXML(bean));  
  11.         fail("重命名后的XML");  
  12.         //类重命名  
  13.         //xstream.alias("account", Student.class);  
  14.         //xstream.alias("生日", Birthday.class);  
  15.         //xstream.aliasField("生日", Student.class, "birthday");  
  16.         //xstream.aliasField("生日", Birthday.class, "birthday");  
  17.         //fail(xstream.toXML(bean));  
  18.         //属性重命名  
  19.         xstream.aliasField("邮件", Student.class"email");  
  20.         //包重命名  
  21.         xstream.aliasPackage("hoo""com.hoo.entity");  
  22.         fail(xstream.toXML(bean));  
  23.     } catch (Exception e) {  
  24.         e.printStackTrace();  
  25.     }  
  26. }  

看结果中的第一份xml内容,是没有经过然后修改或重命名的文档,按照原样输出。文档中的第二份文档的package经过重命名,email属性也经过重命名以及类名也可以进行重命名的。

运行后结果如下: 

------------Bean->XML------------
     
     
     
     
[html] view plain copy
  1. <com.hoo.entity.Student>  
  2.   <id>1id>  
  3.   <name>jackname>  
  4.   <email>[email protected]email>  
  5.   <address>chinaaddress>  
  6.   <birthday>  
  7.     <birthday>2010-11-22birthday>  
  8.   birthday>  
  9. com.hoo.entity.Student>  
  10. 重命名后的XML  
  11. <hoo.Student>  
  12.   <id>1id>  
  13.   <name>jackname>  
  14.   <邮件>[email protected]邮件>  
  15.   <address>chinaaddress>  
  16.   <birthday>  
  17.     <birthday>2010-11-22birthday>  
  18.   birthday>  
  19. hoo.Student>  

2、 将List集合转换成xml文档

     
     
     
     
[java] view plain copy
  1. /** 
  2.  * function:将Java的List集合转换成XML对象 
  3.  * @author hoojo 
  4.  * @createDate Nov 27, 2010 12:20:07 PM 
  5.  */  
  6. @Test  
  7. public void writeList2XML() {  
  8.     try {  
  9.         //修改元素名称  
  10.         xstream.alias("beans", ListBean.class);  
  11.         xstream.alias("student", Student.class);  
  12.         fail("----------List-->XML----------");  
  13.         ListBean listBean = new ListBean();  
  14.         listBean.setName("this is a List Collection");  
  15.           
  16.         List list = new ArrayList();  
  17.         list.add(bean);  
  18.         list.add(bean);//引用bean  
  19.         //list.add(listBean);//引用listBean,父元素  
  20.           
  21.         bean = new Student();  
  22.         bean.setAddress("china");  
  23.         bean.setEmail("[email protected]");  
  24.         bean.setId(2);  
  25.         bean.setName("tom");  
  26.         Birthday day = new Birthday("2010-11-22");  
  27.         bean.setBirthday(day);  
  28.           
  29.         list.add(bean);  
  30.         listBean.setList(list);  
  31.           
  32.         //将ListBean中的集合设置空元素,即不显示集合元素标签  
  33.         //xstream.addImplicitCollection(ListBean.class, "list");  
  34.           
  35.         //设置reference模型  
  36.         //xstream.setMode(XStream.NO_REFERENCES);//不引用  
  37.         xstream.setMode(XStream.ID_REFERENCES);//id引用  
  38.         //xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);//绝对路径引用  
  39.             
  40.         //将name设置为父类(Student)的元素的属性  
  41.         xstream.useAttributeFor(Student.class"name");  
  42.         xstream.useAttributeFor(Birthday.class"birthday");  
  43.         //修改属性的name  
  44.         xstream.aliasAttribute("姓名""name");  
  45.         xstream.aliasField("生日", Birthday.class"birthday");  
  46.         
  47.         fail(xstream.toXML(listBean));  
  48.     } catch (Exception e) {  
  49.         e.printStackTrace();  
  50.     }  
  51. }  
  52. 上面的代码运行后,结果如下: 

    ----------List-->XML----------
         
         
         
         
    [html] view plain copy
    1. <beans id="1">  
    2.   <name>this is a List Collectionname>  
    3.   <list id="2">  
    4.     <student id="3" 姓名="jack">  
    5.       <id>1id>  
    6.       <email>[email protected]email>  
    7.       <address>chinaaddress>  
    8.       <birthday id="4" 生日="2010-11-22"/>  
    9.     student>  
    10.     <student reference="3"/>  
    11.     <student id="5" 姓名="tom">  
    12.       <id>2id>  
    13.       <email>[email protected]email>  
    14.       <address>chinaaddress>  
    15.       <birthday id="6" 生日="2010-11-22"/>  
    16.     student>  
    17.   list>  
    18. beans>  
     
       

    如果不加xstream.addImplicitCollection(ListBean.class, "list");

    这个设置的话,会出现一个List节点包裹着Student节点元素。添加addImplicitCollection可以忽略这个list节点元素。那么上面的list节点就不存在,只会在beans元素中出现name、student这2个xml元素标签;

    setMode是设置相同的对象的引用方式,如果设置XStream.NO_REFERENCES就是不引用,会输出2分相同的Student元素。如果是XStream.ID_REFERENCES会引用相同的那个对象的id属性,如果是XStream.XPATH_ABSOLUTE_REFERENCES引用,那么它将显示xpath路径。上面采用的id引用,这个引用了id=3的那个student标签元素;

    useAttributeFor是设置某个节点显示到父节点的属性中,也就是将指定class中的指定属性,在这个class元素节点的属性中显示。

    如:hoojo

    设置好后就是这样的结果:

    aliasAttribute是修改属性名称。

    3、 在JavaBean中添加Annotation注解进行重命名设置

    先看看JavaBean的代码 

         
         
         
         
    [java] view plain copy
    1. package com.hoo.entity;  
    2.    
    3. import java.util.Arrays;  
    4. import java.util.Calendar;  
    5. import java.util.GregorianCalendar;  
    6. import java.util.List;  
    7. import com.thoughtworks.xstream.annotations.XStreamAlias;  
    8. import com.thoughtworks.xstream.annotations.XStreamAsAttribute;  
    9. import com.thoughtworks.xstream.annotations.XStreamConverter;  
    10. import com.thoughtworks.xstream.annotations.XStreamImplicit;  
    11. import com.thoughtworks.xstream.annotations.XStreamOmitField;  
    12.    
    13. @XStreamAlias("class")  
    14. public class Classes {  
    15.       
    16.     /* 
    17.      * 设置属性显示 
    18.      */  
    19.     @XStreamAsAttribute  
    20.     @XStreamAlias("名称")  
    21.     private String name;  
    22.       
    23.     /* 
    24.      * 忽略 
    25.      */  
    26.     @XStreamOmitField  
    27.     private int number;  
    28.       
    29.     @XStreamImplicit(itemFieldName = "Students")  
    30.     private List students;  
    31.       
    32.     @SuppressWarnings("unused")  
    33.     @XStreamConverter(SingleValueCalendarConverter.class)  
    34.     private Calendar created = new GregorianCalendar();  
    35.    
    36.       
    37.     public Classes(){}  
    38.     public Classes(String name, Student... stu) {  
    39.         this.name = name;  
    40.         this.students = Arrays.asList(stu);  
    41.     }  
    42.     //getter、setter  
    43. }  

    SingleValueCalendarConverter.java这个是一个类型转换器

         
         
         
         
    [java] view plain copy
    1. package com.hoo.entity;  
    2.    
    3. import java.util.Calendar;  
    4. import java.util.Date;  
    5. import java.util.GregorianCalendar;  
    6. import com.thoughtworks.xstream.converters.Converter;  
    7. import com.thoughtworks.xstream.converters.MarshallingContext;  
    8. import com.thoughtworks.xstream.converters.UnmarshallingContext;  
    9. import com.thoughtworks.xstream.io.HierarchicalStreamReader;  
    10. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;  
    11.    
    12. public class SingleValueCalendarConverter implements Converter {  
    13.      public void marshal(Object source, HierarchicalStreamWriter writer,  
    14.                 MarshallingContext context) {  
    15.             Calendar calendar = (Calendar) source;  
    16.             writer.setValue(String.valueOf(calendar.getTime().getTime()));  
    17.         }  
    18.    
    19.         public Object unmarshal(HierarchicalStreamReader reader,  
    20.                 UnmarshallingContext context) {  
    21.             GregorianCalendar calendar = new GregorianCalendar();  
    22.             calendar.setTime(new Date(Long.parseLong(reader.getValue())));  
    23.             return calendar;  
    24.         }  
    25.    
    26.         @SuppressWarnings("unchecked")  
    27.         public boolean canConvert(Class type) {  
    28.             return type.equals(GregorianCalendar.class);  
    29.         }  
    30. }  
    31. 再看看测试用例代码  
    32. @Test  
    33. public void writeList2XML4Annotation() {  
    34.     try {  
    35.         failRed("---------annotation Bean --> XML---------");  
    36.         Student stu = new Student();  
    37.         stu.setName("jack");  
    38.         Classes c = new Classes("一班", bean, stu);  
    39.         c.setNumber(2);  
    40.         //对指定的类使用Annotation  
    41.         //xstream.processAnnotations(Classes.class);  
    42.         //启用Annotation  
    43.         //xstream.autodetectAnnotations(true);  
    44.         xstream.alias("student", Student.class);  
    45.         fail(xstream.toXML(c));  
    46.     } catch (Exception e) {  
    47.         e.printStackTrace();  
    48.     }  
    49. }  

    当启用annotation或是对某个特定的类启用annotation时,上面的classes这个类才有效果。如果不启用annotation,运行后结果如下:

    ---------annotation Bean --> XML---------
         
         
         
         
    [html] view plain copy
    1. <com.hoo.entity.Classes>  
    2.   <name>一班name>  
    3.   <number>2number>  
    4.   <students class="java.util.Arrays$ArrayList">  
    5.     <a class="student-array">  
    6.       <student>  
    7.         <id>1id>  
    8.         <name>jackname>  
    9.         <email>[email protected]email>  
    10.         <address>chinaaddress>  
    11.         <birthday>  
    12.           <birthday>2010-11-22birthday>  
    13.         birthday>  
    14.       student>  
    15.       <student>  
    16.         <id>0id>  
    17.         <name>jackname>  
    18.       student>  
    19.     a>  
    20.   students>  
    21.   <created>  
    22.     <time>1303292056718time>  
    23.     <timezone>Asia/Shanghaitimezone>  
    24.   created>  
    25. com.hoo.entity.Classes>  

    当启用annotation后xstream.processAnnotations(Classes.class),结果如下:

    ---------annotation Bean --> XML---------
         
         
         
         
    [html] view plain copy
    1. <class 名称="一班">  
    2.   <Students>  
    3.     <id>1id>  
    4.     <name>jackname>  
    5.     <email>[email protected]email>  
    6.     <address>chinaaddress>  
    7.     <birthday>  
    8.       <birthday>2010-11-22birthday>  
    9.     birthday>  
    10.   Students>  
    11.   <Students>  
    12.     <id>0id>  
    13.     <name>jackname>  
    14.   Students>  
    15.   <created>1303292242937created>  
    16. class>  

    4、 Map集合转换xml文档 

         
         
         
         
    [java] view plain copy
    1. /** 
    2.  * function:Java Map集合转XML 
    3.  * @author hoojo 
    4.  * @createDate Nov 27, 2010 1:13:26 PM 
    5.  */  
    6. @Test  
    7. public void writeMap2XML() {  
    8.     try {  
    9.         failRed("---------Map --> XML---------");  
    10.         Map map = new HashMap();  
    11.         map.put("No.1", bean);//put  
    12.           
    13.         bean = new Student();  
    14.         bean.setAddress("china");  
    15.         bean.setEmail("[email protected]");  
    16.         bean.setId(2);  
    17.         bean.setName("tom");  
    18.         Birthday day = new Birthday("2010-11-22");  
    19.         bean.setBirthday(day);  
    20.         map.put("No.2", bean);//put  
    21.           
    22.         bean = new Student();  
    23.         bean.setName("jack");  
    24.         map.put("No.3", bean);//put  
    25.           
    26.         xstream.alias("student", Student.class);  
    27.         xstream.alias("key", String.class);  
    28.         xstream.useAttributeFor(Student.class"id");  
    29.         xstream.useAttributeFor("birthday", String.class);  
    30.         fail(xstream.toXML(map));  
    31.     } catch (Exception e) {  
    32.         e.printStackTrace();  
    33.     }  
    34. }  

    运行后结果如下: 

    ---------Map --> XML---------
         
         
         
         
    [html] view plain copy
    1. <map>  
    2.   <entry>  
    3.     <key>No.3key>  
    4.     <student id="0">  
    5.       <name>jackname>  
    6.     student>  
    7.   entry>  
    8.   <entry>  
    9.     <key>No.1key>  
    10.     <student id="1">  
    11.       <name>jackname>  
    12.       <email>[email protected]email>  
    13.       <address>chinaaddress>  
    14.       <birthday birthday="2010-11-22"/>  
    15.     student>  
    16.   entry>  
    17.   <entry>  
    18.     <key>No.2key>  
    19.     <student id="2">  
    20.       <name>tomname>  
    21.       <email>[email protected]email>  
    22.       <address>chinaaddress>  
    23.       <birthday birthday="2010-11-22"/>  
    24.     student>  
    25.   entry>  
    26. map>  

    5、 用OutStream输出流写XML

         
         
         
         
    [java] view plain copy
    1. /** 
    2.  * function:用OutStream输出流写XML 
    3.  * @author hoojo 
    4.  * @createDate Nov 27, 2010 1:13:48 PM 
    5.  */  
    6. @Test  
    7. public void writeXML4OutStream() {  
    8.     try {  
    9.         out = xstream.createObjectOutputStream(System.out);  
    10.         Student stu = new Student();  
    11.         stu.setName("jack");  
    12.         Classes c = new Classes("一班", bean, stu);  
    13.         c.setNumber(2);  
    14.         failRed("---------ObjectOutputStream # JavaObject--> XML---------");  
    15.         out.writeObject(stu);  
    16.         out.writeObject(new Birthday("2010-05-33"));  
    17.         out.write(22);//byte  
    18.         out.writeBoolean(true);  
    19.         out.writeFloat(22.f);  
    20.         out.writeUTF("hello");  
    21.           
    22.     } catch (Exception e) {  
    23.         e.printStackTrace();  
    24.     }  
    25. }  

    使用输出流后,可以通过流对象完成xml的构建,即使没有JavaBean对象,你可以用流来构建一个复杂的xml文档,运行后结果如下:

    ---------ObjectOutputStream # JavaObject--> XML---------
         
         
         
         
    [html] view plain copy
    1. <object-stream>  
    2.   <com.hoo.entity.Student>  
    3.     <id>0id>  
    4.     <name>jackname>  
    5.   com.hoo.entity.Student>  
    6.   <com.hoo.entity.Birthday>  
    7.     <birthday>2010-05-33birthday>  
    8.   com.hoo.entity.Birthday>  
    9.   <byte>22byte>  
    10.   <boolean>trueboolean>  
    11.   <float>22.0float>  
    12.   <string>hellostring>  
    13. object-stream>  

    二、XML内容转换Java对象

    1、 用InputStream将XML文档转换成java对象

         
         
         
         
    [java] view plain copy
    1. /** 
    2.  * function:用InputStream将XML文档转换成java对象  
    3.  * 需要额外的jar xpp3-main.jar 
    4.  * @author hoojo 
    5.  * @createDate Nov 27, 2010 1:14:52 PM 
    6.  */  
    7. @Test  
    8. public void readXML4InputStream() {  
    9.     try {  
    10.         String s = "0jack" +  
    11.           "2010-05-33" +  
    12.           "22true22.0" +  
    13.           "hello";  
    14.         failRed("---------ObjectInputStream## XML --> javaObject---------");  
    15.         StringReader reader = new StringReader(s);  
    16.         in = xstream.createObjectInputStream(reader);  
    17.         Student stu = (Student) in.readObject();  
    18.         Birthday b = (Birthday) in.readObject();  
    19.         byte i = in.readByte();  
    20.         boolean bo = in.readBoolean();  
    21.         float f = in.readFloat();  
    22.         String str = in.readUTF();  
    23.         System.out.println(stu);  
    24.         System.out.println(b);  
    25.         System.out.println(i);  
    26.         System.out.println(bo);  
    27.         System.out.println(f);  
    28.         System.out.println(str);  
    29.     } catch (Exception e) {  
    30.         e.printStackTrace();  
    31.     }  
    32. }  

    读取后,转换的Java对象,结果如下: 

    ---------ObjectInputStream## XML --> javaObject---------
    
         
         
         
         
    [html] view plain copy
    1. jack#0#null#null#null  
    2. 2010-05-33  
    3. 22  
    4. true  
    5. 22.0  
    6. hello  

    2、 将xml文档转换成Java对象 

         
         
         
         
    [java] view plain copy
    1. /** 
    2.  * function:将XML字符串转换成Java对象 
    3.  * @author hoojo 
    4.  * @createDate Nov 27, 2010 2:39:06 PM 
    5.  */  
    6. @Test  
    7. public void readXml2Object() {  
    8.     try {  
    9.         failRed("-----------Xml >>> Bean--------------");  
    10.         Student stu = (Student) xstream.fromXML(xstream.toXML(bean));  
    11.         fail(stu.toString());  
    12.           
    13.         List list = new ArrayList();  
    14.         list.add(bean);//add  
    15.           
    16.         Map map = new HashMap();  
    17.         map.put("No.1", bean);//put  
    18.           
    19.         bean = new Student();  
    20.         bean.setAddress("china");  
    21.         bean.setEmail("[email protected]");  
    22.         bean.setId(2);  
    23.         bean.setName("tom");  
    24.         Birthday day = new Birthday("2010-11-22");  
    25.         bean.setBirthday(day);  
    26.         list.add(bean);//add  
    27.         map.put("No.2", bean);//put  
    28.           
    29.         bean = new Student();  
    30.         bean.setName("jack");  
    31.         list.add(bean);//add  
    32.         map.put("No.3", bean);//put  
    33.           
    34.         failRed("==========XML >>> List===========");  
    35.         List studetns = (List) xstream.fromXML(xstream.toXML(list));  
    36.         fail("size:" + studetns.size());//3  
    37.         for (Student s : studetns) {  
    38.             fail(s.toString());  
    39.         }  
    40.           
    41.         failRed("==========XML >>> Map===========");  
    42.         Map maps = (Map) xstream.fromXML(xstream.toXML(map));  
    43.         fail("size:" + maps.size());//3  
    44.         Set key = maps.keySet();  
    45.         Iterator iter = key.iterator();  
    46.         while (iter.hasNext()) {  
    47.             String k = iter.next();  
    48.             fail(k + ":" + map.get(k));  
    49.         }  
    50.     } catch (Exception e) {  
    51.         e.printStackTrace();  
    52.     }  
    53. }  

    运行后结果如下: 

    -----------Xml >>> Bean--------------
         
         
         
         
    [html] view plain copy
    1. jack#1#china#2010-11-22#jack@email.com  
    2. ==========XML >>> List===========  
    3. size:3  
    4. jack#1#china#2010-11-22#[email protected]  
    5. tom#2#china#2010-11-22#[email protected]  
    6. jack#0#null#null#null  
    7. ==========XML >>> Map===========  
    8. size:3  
    9. No.3:jack#0#null#null#null  
    10. No.1:jack#1#china#2010-11-22#[email protected]  
    11. No.2:tom#2#china#2010-11-22#[email protected]  

    怎么样,成功的完成XML到JavaBean、List、Map的转换,更多对象转换还需要大家一一尝试。用法类似~这里就不一样赘述。


    三、XStream对JSON的支持

    xStream对JSON也有非常好的支持,它提供了2个模型驱动。用这2个驱动可以完成Java对象到JSON的相互转换。使用JettisonMappedXmlDriver驱动,将Java对象转换成json,需要添加jettison.jar

    1、 用JettisonMappedXmlDriver完成Java对象到JSON的转换

         
         
         
         
    [java] view plain copy
    1. /** 
    2.  * function:XStream结合JettisonMappedXmlDriver驱动,转换Java对象到JSON 
    3.  * 需要添加jettison jar 
    4.  * @author hoojo 
    5.  * @createDate Nov 27, 2010 1:23:18 PM 
    6.  */  
    7. @Test  
    8. public void writeEntity2JETTSON() {  
    9.     failRed("=======JettisonMappedXmlDriver===JavaObject >>>> JaonString=========");  
    10.     xstream = new XStream(new JettisonMappedXmlDriver());  
    11.     xstream.setMode(XStream.NO_REFERENCES);  
    12.     xstream.alias("student", Student.class);  
    13.     fail(xstream.toXML(bean));  
    14. }  

    运行后结果如下: 

    =======JettisonMappedXmlDriver===JavaObject >>>> JaonString=========
         
         
         
         
    [html] view plain copy
    1. {"student":{"id":1,"name":"jack","email":"[email protected]","address":"china","birthday":[{},"2010-11-22"]}}  

    JSON的转换和XML的转换用法一样,只是创建XStream需要传递一个参数,这个参数就是xml到JSON映射转换的驱动。这里会降到两个驱动,分别是JettisonMappedXmlDriver、JsonHierarchicalStreamDriver。


    2、 JsonHierarchicalStreamDriver完成Java对象到JSON的转换

         
         
         
         
    [java] view plain copy
    1. /** 
    2.  * function:用XStream结合JsonHierarchicalStreamDriver驱动 
    3.  * 转换java对象为JSON字符串 
    4.  * @author hoojo 
    5.  * @createDate Nov 27, 2010 1:16:46 PM 
    6.  */  
    7. @Test  
    8. public void writeEntiry2JSON() {  
    9.     failRed("======JsonHierarchicalStreamDriver====JavaObject >>>> JaonString=========");  
    10.     xstream = new XStream(new JsonHierarchicalStreamDriver());  
    11.     //xstream.setMode(XStream.NO_REFERENCES);  
    12.     xstream.alias("student", Student.class);  
    13.     failRed("-------Object >>>> JSON---------");  
    14.     fail(xstream.toXML(bean));  
    15.       
    16.     //failRed("========JsonHierarchicalStreamDriver==删除根节点=========");  
    17.     //删除根节点  
    18.     xstream = new XStream(new JsonHierarchicalStreamDriver() {  
    19.         public HierarchicalStreamWriter createWriter(Writer out) {  
    20.             return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE);  
    21.         }  
    22.     });  
    23.     //xstream.setMode(XStream.NO_REFERENCES);  
    24.     xstream.alias("student", Student.class);  
    25.     fail(xstream.toXML(bean));  
    26. }  

    运行后结果如下: 

    ======JsonHierarchicalStreamDriver====JavaObject >>>> JaonString=========
         
         
         
         
    [html] view plain copy
    1. -------Object >>>> JSON---------  
    2. {"student": {  
    3.   "id": 1,  
    4.   "name": "jack",  
    5.   "email": "[email protected]",  
    6.   "address": "china",  
    7.   "birthday": {  
    8.     "birthday": "2010-11-22"  
    9.   }  
    10. }}  
    11. {  
    12.   "id": 1,  
    13.   "name": "jack",  
    14.   "email": "[email protected]",  
    15.   "address": "china",  
    16.   "birthday": {  
    17.     "birthday": "2010-11-22"  
    18.   }  
    19. }  

    使用JsonHierarchicalStreamDriver转换默认会给转换后的对象添加一个根节点,但是在构建JsonHierarchicalStreamDriver驱动的时候,你可以重写createWriter方法,删掉根节点。

    看上面的结果,一个是默认带根节点的JSON对象,它只是将类名作为一个属性,将对象作为该属性的一个值。而另一个没有带根属性的JSON就是通过重写createWriter方法完成的。


    3、 将List集合转换成JSON字符串

         
         
         
         
    [java] view plain copy
    1. @Test  
    2. public void writeList2JSON() {  
    3.     failRed("======JsonHierarchicalStreamDriver====JavaObject >>>> JaonString=========");  
    4.     JsonHierarchicalStreamDriver driver = new JsonHierarchicalStreamDriver();  
    5.     xstream = new XStream(driver);  
    6.     //xstream = new XStream(new JettisonMappedXmlDriver());//转换错误  
    7.     //xstream.setMode(XStream.NO_REFERENCES);  
    8.     xstream.alias("student", Student.class);  
    9.       
    10.     List list = new ArrayList();  
    11.     list.add(bean);//add  
    12.       
    13.     bean = new Student();  
    14.     bean.setAddress("china");  
    15.     bean.setEmail("[email protected]");  
    16.     bean.setId(2);  
    17.     bean.setName("tom");  
    18.     Birthday day = new Birthday("2010-11-22");  
    19.     bean.setBirthday(day);  
    20.     list.add(bean);//add  
    21.       
    22.     bean = new Student();  
    23.     bean.setName("jack");  
    24.     list.add(bean);//add  
    25.       
    26.     fail(xstream.toXML(list));  
    27.       
    28.     //failRed("========JsonHierarchicalStreamDriver==删除根节点=========");  
    29.     //删除根节点  
    30.     xstream = new XStream(new JsonHierarchicalStreamDriver() {  
    31.         public HierarchicalStreamWriter createWriter(Writer out) {  
    32.             return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE);  
    33.         }  
    34.     });  
    35.     xstream.alias("student", Student.class);  
    36.     fail(xstream.toXML(list));  
    37. }  

    运行后结果如下 

    ======JsonHierarchicalStreamDriver====JavaObject >>>> JaonString=========
         
         
         
         
    [html] view plain copy
    1. ##{"list": [  
    2.   {  
    3.     "id": 1,  
    4.     "name": "jack",  
    5.     "email": "[email protected]",  
    6.     "address": "china",  
    7.     "birthday": {  
    8.       "birthday": "2010-11-22"  
    9.     }  
    10.   },  
    11.   {  
    12.     "id": 2,  
    13.     "name": "tom",  
    14.     "email": "[email protected]",  
    15.     "address": "china",  
    16.     "birthday": {  
    17.       "birthday": "2010-11-22"  
    18.     }  
    19.   },  
    20.   {  
    21.     "id": 0,  
    22.     "name": "jack"  
    23.   }  
    24. ]}  
    25. #[  
    26.   {  
    27.     "id": 1,  
    28.     "name": "jack",  
    29.     "email": "[email protected]",  
    30.     "address": "china",  
    31.     "birthday": {  
    32.       "birthday": "2010-11-22"  
    33.     }  
    34.   },  
    35.   {  
    36.     "id": 2,  
    37.     "name": "tom",  
    38.     "email": "[email protected]",  
    39.     "address": "china",  
    40.     "birthday": {  
    41.       "birthday": "2010-11-22"  
    42.     }  
    43.   },  
    44.   {  
    45.     "id": 0,  
    46.     "name": "jack"  
    47.   }  
    48. ]  

    上面的list1是使用JsonHierarchicalStreamDriver 转换的,当然你也可以使用JettisonMappedXmlDriver驱动进行转换;用JettisonMappedXmlDriver转换后,你会发现格式不同而且没有根属性。


    4、 Map转换json 

         
         
         
         
    [java] view plain copy
    1. @Test  
    2. public void writeMap2JSON() {  
    3.     failRed("======JsonHierarchicalStreamDriver==== Map >>>> JaonString=========");  
    4.     xstream = new XStream(new JsonHierarchicalStreamDriver());  
    5.     //xstream = new XStream(new JettisonMappedXmlDriver());  
    6.     xstream.alias("student", Student.class);  
    7.       
    8.     Map map = new HashMap();  
    9.     map.put("No.1", bean);//put  
    10.       
    11.     bean = new Student();  
    12.     bean.setAddress("china");  
    13.     bean.setEmail("[email protected]");  
    14.     bean.setId(2);  
    15.     bean.setName("tom");  
    16.     bean.setBirthday(new Birthday("2010-11-21"));  
    17.     map.put("No.2", bean);//put  
    18.       
    19.     bean = new Student();  
    20.     bean.setName("jack");  
    21.     map.put("No.3", bean);//put  
    22.       
    23.     fail(xstream.toXML(map));  
    24.       
    25.     //failRed("========JsonHierarchicalStreamDriver==删除根节点=========");  
    26.     //删除根节点  
    27.     xstream = new XStream(new JsonHierarchicalStreamDriver() {  
    28.         public HierarchicalStreamWriter createWriter(Writer out) {  
    29.             return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE);  
    30.         }  
    31.     });  
    32.     xstream.alias("student", Student.class);  
    33.     fail(xstream.toXML(map));  
    34. }  

    运行后结果如下: 

    ======JsonHierarchicalStreamDriver==== Map >>>> JaonString=========
         
         
         
         
    [html] view plain copy
    1. {"map": [  
    2.   [  
    3.     "No.3",  
    4.     {  
    5.       "id": 0,  
    6.       "name": "jack"  
    7.     }  
    8.   ],  
    9.   [  
    10.     "No.1",  
    11.     {  
    12.       "id": 1,  
    13.       "name": "jack",  
    14.       "email": "[email protected]",  
    15.       "address": "china",  
    16.       "birthday": {  
    17.         "birthday": "2010-11-22"  
    18.       }  
    19.     }  
    20.   ],  
    21.   [  
    22.     "No.2",  
    23.     {  
    24.       "id": 2,  
    25.       "name": "tom",  
    26.       "email": "[email protected]",  
    27.       "address": "china",  
    28.       "birthday": {  
    29.         "birthday": "2010-11-21"  
    30.       }  
    31.     }  
    32.   ]  
    33. ]}  
    34. [  
    35.   [  
    36.     "No.3",  
    37.     {  
    38.       "id": 0,  
    39.       "name": "jack"  
    40.     }  
    41.   ],  
    42.   [  
    43.     "No.1",  
    44.     {  
    45.       "id": 1,  
    46.       "name": "jack",  
    47.       "email": "[email protected]",  
    48.       "address": "china",  
    49.       "birthday": {  
    50.         "birthday": "2010-11-22"  
    51.       }  
    52.     }  
    53.   ],  
    54.   [  
    55.     "No.2",  
    56.     {  
    57.       "id": 2,  
    58.       "name": "tom",  
    59.       "email": "[email protected]",  
    60.       "address": "china",  
    61.       "birthday": {  
    62.         "birthday": "2010-11-21"  
    63.       }  
    64.     }  
    65.   ]  
    66. ]  

    5、 将JSON转换java对象

    [java]  view plain  copy
    1. /** 
    2.  * function:JsonHierarchicalStreamDriver可以将简单的json字符串转换成java对象,list、map转换不成功; 
    3.  * JsonHierarchicalStreamDriver读取JSON字符串到java对象出错 
    4.  * @author hoojo 
    5.  * @createDate Nov 27, 2010 1:22:26 PM 
    6.  * @throws JSONException 
    7.  */  
    8. @Test  
    9. public void readJSON2Object() throws JSONException {  
    10.     String json = "{\"student\": {" +  
    11.         "\"id\": 1," +  
    12.         "\"name\": \"haha\"," +  
    13.         "\"email\": \"email\"," +  
    14.         "\"address\": \"address\"," +  
    15.         "\"birthday\": {" +  
    16.             "\"birthday\": \"2010-11-22\"" +  
    17.         "}" +  
    18.     "}}";  
    19.     //JsonHierarchicalStreamDriver读取JSON字符串到java对象出错,但JettisonMappedXmlDriver可以  
    20.     xstream = new XStream(new JettisonMappedXmlDriver());  
    21.     xstream.alias("student", Student.class);  
    22.     fail(xstream.fromXML(json).toString());  
    23.       
    24.     //JettisonMappedXmlDriver转换List集合出错,但JsonHierarchicalStreamDriver可以转换正确  
    25.     //JettisonMappedXmlDriver 转换的字符串 {"list":{"student":[{"id":1,"name":"haha","email":"email","address":"address","birthday":[{},"2010-11-22"]}]},"student":{"id":2,"name":"tom","email":"[email protected]","address":"china","birthday":[{},"2010-11-22"]}}  
    26.     json = "{\"list\": [{" +  
    27.             "\"id\": 1," +  
    28.             "\"name\": \"haha\"," +  
    29.             "\"email\": \"email\"," +  
    30.             "\"address\": \"address\"," +  
    31.             "\"birthday\": {" +  
    32.               "\"birthday\": \"2010-11-22\"" +  
    33.             "}" +  
    34.            "},{" +  
    35.             "\"id\": 2," +  
    36.             "\"name\": \"tom\"," +  
    37.             "\"email\": \"[email protected]\"," +  
    38.             "\"address\": \"china\"," +  
    39.             "\"birthday\": {" +  
    40.               "\"birthday\": \"2010-11-22\"" +  
    41.             "}" +  
    42.           "}]}";  
    43.     System.out.println(json);//用js转换成功  
    44.     List list = (List) xstream.fromXML(json);  
    45.     System.out.println(list.size());//0好像转换失败  
    46. }  

    运行后结果如下: 

         
         
         
         
    [html] view plain copy
    1. haha#1#address#2010-11-22#email  
    2. {"list": [{"id": 1,"name": "haha","email": "email","address": "address","birthday": {"birthday": "2010-11-22"}},  
    3. {"id": 2,"name": "tom","email": "[email protected]","address": "china","birthday": {"birthday": "2010-11-22"}}]}  
    4. 0  

    JSON到Java的转换是fromXML方法。


    四.android源码实例

    上面的代码是不是还不够过瘾?Xstream原则上只要是符合XML和JSON语法规范的都能可以转换成对象形式.

    AndroidXstream示例下载 逐个手敲测试倾情奉上


    你可能感兴趣的:(android,xml)