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環境下都適用


測試用例代碼

  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 [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.      * <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("[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.      * <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

  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------------
  1. <com.hoo.entity.Student>  
  2.   <id>1</id>  
  3.   <name>jack</name>  
  4.   <email>[email protected]</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.   <郵件>[email protected]</郵件>  
  15.   <address>china</address>  
  16.   <birthday>  
  17.     <birthday>2010-11-22</birthday>  
  18.   </birthday>  
  19. </hoo.Student>  

2、 將List集合轉換成xml文檔

  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("[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. }  

上面的代碼運行後,結果如下: 

----------List-->XML----------
  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>[email protected]</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>[email protected]</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的代碼 

  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這個是一個類型轉換器

  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---------
  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>[email protected]</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---------
  1. <class 名稱="一班">  
  2.   <Students>  
  3.     <id>1</id>  
  4.     <name>jack</name>  
  5.     <email>[email protected]</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文檔 

  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("[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---------
  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>[email protected]</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>[email protected]</email>  
  22.       <address>china</address>  
  23.       <birthday birthday="2010-11-22"/>  
  24.     </student>  
  25.   </entry>  
  26. </map>  

5、 用OutStream輸出流寫XML

  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---------
  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對象

  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---------
  1. jack#0#null#null#null  
  2. 2010-05-33  
  3. 22  
  4. true  
  5. 22.0  
  6. hello  

2、 將xml文檔轉換成Java對象 

  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("[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<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--------------
  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的轉換

  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=========
  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的轉換

  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=========
  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字符串

  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("[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=========
  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 

  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("[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=========
  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.  * <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":"[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. }  

運行後結果如下: 

  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示例下載 逐個手敲測試傾情奉上


發佈了88 篇原創文章 · 獲贊 87 · 訪問量 93萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章