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

来源:互联网 发布:神速淘宝图片下载器 编辑:程序博客网 时间:2024/06/04 22:47

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.  * <b>function:</b>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 hoojo_@126.com 
  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.      * <b>function:</b>初始化资源准备 
  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("jack@email.com");  
  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.      * <b>function:</b>释放对象资源 
  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.  * <b>function:</b>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>1</id>  
  3.   <name>jack</name>  
  4.   <email>jack@email.com</email>  
  5.   <address>china</address>  
  6.   <birthday>  
  7.     <birthday>2010-11-22</birthday>  
  8.   </birthday>  
  9. </com.hoo.entity.Student>  
  10. 重命名后的XML  
  11. <hoo.Student>  
  12.   <id>1</id>  
  13.   <name>jack</name>  
  14.   <邮件>jack@email.com</邮件>  
  15.   <address>china</address>  
  16.   <birthday>  
  17.     <birthday>2010-11-22</birthday>  
  18.   </birthday>  
  19. </hoo.Student>  

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

[java] view plain copy
  1. /** 
  2.  * <b>function:</b>将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<Object> list = new ArrayList<Object>();  
  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("tom@125.com");  
  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. }  

上面的代码运行后,结果如下: 

----------List-->XML----------
[html] view plain copy
  1. <beans id="1">  
  2.   <name>this is a List Collection</name>  
  3.   <list id="2">  
  4.     <student id="3" 姓名="jack">  
  5.       <id>1</id>  
  6.       <email>jack@email.com</email>  
  7.       <address>china</address>  
  8.       <birthday id="4" 生日="2010-11-22"/>  
  9.     </student>  
  10.     <student reference="3"/>  
  11.     <student id="5" 姓名="tom">  
  12.       <id>2</id>  
  13.       <email>tom@125.com</email>  
  14.       <address>china</address>  
  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引用,<student reference="3"/>这个引用了id=3的那个student标签元素;

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

如:<student><name>hoojo</name></student>

设置好后就是这样的结果:<student name=”hoojo”></student>

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<Student> 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>2</number>  
  4.   <students class="java.util.Arrays$ArrayList">  
  5.     <a class="student-array">  
  6.       <student>  
  7.         <id>1</id>  
  8.         <name>jack</name>  
  9.         <email>jack@email.com</email>  
  10.         <address>china</address>  
  11.         <birthday>  
  12.           <birthday>2010-11-22</birthday>  
  13.         </birthday>  
  14.       </student>  
  15.       <student>  
  16.         <id>0</id>  
  17.         <name>jack</name>  
  18.       </student>  
  19.     </a>  
  20.   </students>  
  21.   <created>  
  22.     <time>1303292056718</time>  
  23.     <timezone>Asia/Shanghai</timezone>  
  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>1</id>  
  4.     <name>jack</name>  
  5.     <email>jack@email.com</email>  
  6.     <address>china</address>  
  7.     <birthday>  
  8.       <birthday>2010-11-22</birthday>  
  9.     </birthday>  
  10.   </Students>  
  11.   <Students>  
  12.     <id>0</id>  
  13.     <name>jack</name>  
  14.   </Students>  
  15.   <created>1303292242937</created>  
  16. </class>  

4、 Map集合转换xml文档 

[java] view plain copy
  1. /** 
  2.  * <b>function:</b>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<String, Student> map = new HashMap<String, Student>();  
  11.         map.put("No.1", bean);//put  
  12.           
  13.         bean = new Student();  
  14.         bean.setAddress("china");  
  15.         bean.setEmail("tom@125.com");  
  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.3</key>  
  4.     <student id="0">  
  5.       <name>jack</name>  
  6.     </student>  
  7.   </entry>  
  8.   <entry>  
  9.     <key>No.1</key>  
  10.     <student id="1">  
  11.       <name>jack</name>  
  12.       <email>jack@email.com</email>  
  13.       <address>china</address>  
  14.       <birthday birthday="2010-11-22"/>  
  15.     </student>  
  16.   </entry>  
  17.   <entry>  
  18.     <key>No.2</key>  
  19.     <student id="2">  
  20.       <name>tom</name>  
  21.       <email>tom@125.com</email>  
  22.       <address>china</address>  
  23.       <birthday birthday="2010-11-22"/>  
  24.     </student>  
  25.   </entry>  
  26. </map>  

5、 用OutStream输出流写XML

[java] view plain copy
  1. /** 
  2.  * <b>function:</b>用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>0</id>  
  4.     <name>jack</name>  
  5.   </com.hoo.entity.Student>  
  6.   <com.hoo.entity.Birthday>  
  7.     <birthday>2010-05-33</birthday>  
  8.   </com.hoo.entity.Birthday>  
  9.   <byte>22</byte>  
  10.   <boolean>true</boolean>  
  11.   <float>22.0</float>  
  12.   <string>hello</string>  
  13. </object-stream>  

二、XML内容转换Java对象

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

[java] view plain copy
  1. /** 
  2.  * <b>function:</b>用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 = "<object-stream><com.hoo.entity.Student><id>0</id><name>jack</name>" +  
  11.           "</com.hoo.entity.Student><com.hoo.entity.Birthday><birthday>2010-05-33</birthday>" +  
  12.           "</com.hoo.entity.Birthday><byte>22</byte><boolean>true</boolean><float>22.0</float>" +  
  13.           "<string>hello</string></object-stream>";  
  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.  * <b>function:</b>将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<Student> list = new ArrayList<Student>();  
  14.         list.add(bean);//add  
  15.           
  16.         Map<String, Student> map = new HashMap<String, Student>();  
  17.         map.put("No.1", bean);//put  
  18.           
  19.         bean = new Student();  
  20.         bean.setAddress("china");  
  21.         bean.setEmail("tom@125.com");  
  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<Student> studetns = (List<Student>) 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<String, Student> maps = (Map<String, Student>) xstream.fromXML(xstream.toXML(map));  
  43.         fail("size:" + maps.size());//3  
  44.         Set<String> key = maps.keySet();  
  45.         Iterator<String> 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#jack@email.com  
  5. tom#2#china#2010-11-22#tom@125.com  
  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#jack@email.com  
  11. No.2:tom#2#china#2010-11-22#tom@125.com  

怎么样,成功的完成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.  * <b>function:</b>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":"jack@email.com","address":"china","birthday":[{},"2010-11-22"]}}  

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


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

[java] view plain copy
  1. /** 
  2.  * <b>function:</b>用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": "jack@email.com",  
  6.   "address": "china",  
  7.   "birthday": {  
  8.     "birthday": "2010-11-22"  
  9.   }  
  10. }}  
  11. {  
  12.   "id": 1,  
  13.   "name": "jack",  
  14.   "email": "jack@email.com",  
  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<Student> list = new ArrayList<Student>();  
  11.     list.add(bean);//add  
  12.       
  13.     bean = new Student();  
  14.     bean.setAddress("china");  
  15.     bean.setEmail("tom@125.com");  
  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": "jack@email.com",  
  6.     "address": "china",  
  7.     "birthday": {  
  8.       "birthday": "2010-11-22"  
  9.     }  
  10.   },  
  11.   {  
  12.     "id": 2,  
  13.     "name": "tom",  
  14.     "email": "tom@125.com",  
  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": "jack@email.com",  
  30.     "address": "china",  
  31.     "birthday": {  
  32.       "birthday": "2010-11-22"  
  33.     }  
  34.   },  
  35.   {  
  36.     "id": 2,  
  37.     "name": "tom",  
  38.     "email": "tom@125.com",  
  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<String, Student> map = new HashMap<String, Student>();  
  9.     map.put("No.1", bean);//put  
  10.       
  11.     bean = new Student();  
  12.     bean.setAddress("china");  
  13.     bean.setEmail("tom@125.com");  
  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": "jack@email.com",  
  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": "tom@125.com",  
  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": "jack@email.com",  
  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": "tom@125.com",  
  60.       "address": "china",  
  61.       "birthday": {  
  62.         "birthday": "2010-11-21"  
  63.       }  
  64.     }  
  65.   ]  
  66. ]  

5、 将JSON转换java对象

[java] view plain copy
  1. /** 
  2.  * <b>function:</b>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":"tom@125.com","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\": \"tom@125.com\"," +  
  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": "tom@125.com","address": "china","birthday": {"birthday": "2010-11-22"}}]}  
  4. 0  

JSON到Java的转换是fromXML方法。


四.android源码实例

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

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


原创粉丝点击