java 利用Xstream注解生成和解析xml

知识结构:

1.Xstream简介;

使用限制: JDK版本不能<1.5. 
虽然预处理注解是安全的,但自动侦查注解可能发生竞争条件.

特点:

简化的API; 
无映射文件; 
高性能,低内存占用; 
整洁的XML; 
不需要修改对象;支持内部私有字段,不需要setter/getter方法,final字段;非公有类,内部类;类不需要默认构造器,完全对象图支持.维护对象引用计数,循环引用. i 
提供序列化接口; 
自定义转换类型策略; 
详细的错误诊断; 
快速输出格式;当前支持 JSON 和 morphing.

使用场景

Transport 转换 
Persistence 持久化对象 
Configuration 配置 
Unit Tests 单元测

隐式集合 
当我们使用集合类时不想显示集合,只显示里面的元素即可. 
使用隐式集合前: 
<list> 
 <element /> 
 <element /> 
<list> 

使用隐式集合: 
xstream.addImplicitCollection(Person.class, "list"); 

使用隐式集合后: 
 <element /> 
 <element />

 2.Xstream注解常用知识:

@XStreamAlias("message") 别名注解 
作用目标: 类,字段 
@XStreamImplicit 隐式集合 
@XStreamImplicit(itemFieldName="part") 
作用目标: 集合字段 
@XStreamConverter(SingleValueCalendarConverter.class) 注入转换器 
作用目标: 对象 
@XStreamAsAttribute 转换成属性 
作用目标: 字段 
@XStreamOmitField 忽略字段 
作用目标: 字段 
Auto-detect Annotations 自动侦查注解  
xstream.autodetectAnnotations(true); 
自动侦查注解与XStream.processAnnotations(Class[] cls)的区别在于性能.自动侦查注解将缓存所有类的类型.

3.案例分析:

(1)同一标签下多个同名元素;
(2)同一标签下循环多个对象;

  1.实体类:PersonBean

 

 1 import java.util.List;

 2

 3 import com.thoughtworks.xstream.annotations.XStreamAlias;

 4 import com.thoughtworks.xstream.annotations.XStreamImplicit;

 5

 6 /**

 7  *@ClassName:PersonBean

 8  *@author: chenyoulong  Email: chen.youlong@payeco.com

 9  *@date :2012-9-28 下午3:10:47

10  *@Description:TODO

11  */

12 @XStreamAlias("person")

13 public class PersonBean {

14     @XStreamAlias("firstName")

15     private String firstName;

16     @XStreamAlias("lastName")

17     private String lastName;

18    

19     @XStreamAlias("telphone")

20     private PhoneNumber tel;

21     @XStreamAlias("faxphone")

22     private PhoneNumber fax;

23    

24     //测试一个标签下有多个同名标签

25     @XStreamAlias("friends")

26     private Friends friend;

27    

28     //测试一个标签下循环对象

29     @XStreamAlias("pets")

30     private Pets pet;

31    

32    

33     //省略setter和getter

34 }

 

  2.实体类:PhoneNumber

 

 1 @XStreamAlias("phoneNumber")

 2     public  class PhoneNumber{

 3         @XStreamAlias("code")

 4         private int code;

 5         @XStreamAlias("number")

 6         private String number;

 7        

 8             //省略setter和getter

 9        

10     }

 

  3.实体类:Friends(一个标签下有多个同名标签

 

 1 /**

 2      * 用Xstream注解的方式实现:一个标签下有多个同名标签

 3      *@ClassName:Friends

 4      *@author: chenyoulong  Email: chen.youlong@payeco.com

 5      *@date :2012-9-28 下午4:32:24

 6      *@Description:TODO 5个name 中国,美国,俄罗斯,英国,法国

 7      *http://blog.csdn.net/menhuanxiyou/article/details/5426765

 8      */

 9     public static class Friends{

10         @XStreamImplicit(itemFieldName="name")   //itemFieldName定义重复字段的名称,

11         /*<friends>                                <friends>

12             <name>A1</name>                            <String>A1</String>

13             <name>A2</name>    如果没有,则会变成    =====>        <String>A1</String>

14             <name>A3</name>                            <String>A1</String>

15           </friends>                                </friends>

16       */

17         private List<String> name;

18

19         public List<String> getName() {

20             return name;

21         }

22

23         public void setName(List<String> name) {

24             this.name = name;

25         }

26     }

 

  4.1实体类:Animal(同一标签下循环对象实体1

 

 1 //测试同一标签下循环某一对象

 2     public  class Animal{

 3         @XStreamAlias("name")

 4         private String name;

 5         @XStreamAlias("age")

 6         private int age;

 7         public Animal(String name,int age){

 8             this.name=name;

 9             this.age=age;

10         }

11        

12               //省略setter和getter

13     }

 

  4.2实体类:Pets(同一标签下循环对象实体2

 

 1 /**

 2      * 测试同一标签下循环某一对象

 3      *@ClassName:Pets

 4      *@author: chenyoulong  Email: chen.youlong@payeco.com

 5      *@date :2012-9-28 下午6:26:01

 6      *@Description:TODO

 7      */

 8     public class Pets{

 9         @XStreamImplicit(itemFieldName="pet")

10         private List<Animal> animalList;

11        

12         public List<Animal> getAnimalList() {

13             return animalList;

14         }

15

16         public void setAnimalList(List<Animal> animalList) {

17             this.animalList = animalList;

18         }

19        

20     }

 

  5.main函数示例1toxml

 

 1 import com.thoughtworks.xstream.XStream;

 2 import com.thoughtworks.xstream.io.json.JsonWriter.Format;

 3 import com.thoughtworks.xstream.io.xml.DomDriver;

 4

 5 /**

 6  *@ClassName:PersonTest

 7  *@author: chenyoulong 

 8  *@date :2012-9-28 下午3:25:09

 9  *@Description:TODO

10  */

11 public class PersonTest {

12

13     /**

14      * @Title: main

15      * @Description: TODO

16      * @param args

17      * @return void 

18      */

19     public static void main(String[] args) {

20         // TODO Auto-generated method stub

21        

22         PersonBean per=new PersonBean();

23         per.setFirstName("chen");

24         per.setLastName("youlong");

25        

26         PhoneNumber tel=new PhoneNumber();

27         tel.setCode(137280);

28         tel.setNumber("137280968");

29        

30         PhoneNumber fax=new PhoneNumber();

31         fax.setCode(20);

32         fax.setNumber("020221327");

33         per.setTel(tel);

34         per.setFax(fax);

35        

36        

37         //测试一个标签下有多个同名标签

38         List<String> friendList=new ArrayList<String>();

39         friendList.add("A1");

40         friendList.add("A2");

41         friendList.add("A3");

42         Friends friend1=new Friends();

43         friend1.setName(friendList);

44         per.setFriend(friend1);

45        

46         //测试一个标签下循环对象

47         Animal dog=new Animal("Dolly",2);

48         Animal cat=new Animal("Ketty",2);

49         List<Animal> petList=new ArrayList<Animal>();

50         petList.add(dog);

51         petList.add(cat);

52         Pets pet=new Pets();

53         pet.setAnimalList(petList);

54         per.setPet(pet);

55        

56                     //java对象转换成xml

57         String xml=XmlUtil.toXml(per);

58         System.out.println("xml==="+xml);

59        

60     }

61 }

 

  xml效果图

 

 1 xml===<person>

 2   <firstName>chen</firstName>

 3   <lastName>youlong</lastName>

 4   <telphone>

 5     <code>137280</code>

 6     <number>137280968</number>

 7   </telphone>

 8   <faxphone>

 9     <code>20</code>

10     <number>020221327</number>

11   </faxphone>

12   <friends>

13     <name>A1</name>

14     <name>A2</name>

15     <name>A3</name>

16   </friends>

17   <pets>

18     <pet>

19       <name>doly</name>

20       <age>2</age>

21     </pet>

22     <pet>

23       <name>Ketty</name>

24       <age>2</age>

25     </pet>

26   </pets>

27 </person>

 

  5.2 main函数示例2toBean

 

 1 public static void main(String[] args) {

 2         // TODO Auto-generated method stub

 3        

 4         //toXml

 5 //        String xmlStr=new PersonTest().toXml();

 6        

 7         //toBean

 8 //        PersonBean per=new PersonTest().toBean();

 9         String xmlStr="<person>"+

10                   "<firstName>chen</firstName>"+

11                   "<lastName>youlong</lastName>"+

12                   "<telphone>"+

13                     "<code>137280</code>"+

14                     "<number>137280968</number>"+

15                   "</telphone>"+

16                   "<faxphone>"+

17                     "<code>20</code>"+

18                     "<number>020221327</number>"+

19                   "</faxphone>"+

20                   "<friends>"+

21                     "<name>A1</name>"+

22                     "<name>A2</name>"+

23                     "<name>A3</name>"+

24                   "</friends>"+

25                   "<pets>"+

26                     "<pet>"+

27                       "<name>doly</name>"+

28                       "<age>2</age>"+

29                     "</pet>"+

30                     "<pet>"+

31                       "<name>Ketty</name>"+

32                       "<age>2</age>"+

33                     "</pet>"+

34                   "</pets>"+

35                 "</person>";

36 //用泛型的知识

37         PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class);

38         System.out.println("person=firstname=="+person.getFirstName());

39         System.out.println("person==Friends==name1=="+person.getFriend().getName().get(0));

40         System.out.println("person==Pets==name2=="+person.getPet().getAnimalList().get(1).getName());

41

42 /*

43 //效果与以下方法类同,(以下代码较为直观)

44 XStream xstream=new XStream(new DomDriver()); //注意:不是new Xstream(); 否则报错:

45

46         xstream.processAnnotations(PersonBean.class);

47         PersonBean person=(PersonBean)xstream.fromXML(xmlStr);

48         System.out.println("person=firstname=="+person.getFirstName());

49         System.out.println("person==Friends==name1=="+person.getFriend().getName().get(0));

50         System.out.println("person==Pets==name=="+person.getPet().getAnimalList().get(1).getName());

51 */

52

53        

54     }

 

  6.XmlUtil工具类(toxml()和toBean())

 

  1 /**

  2      * 输出xml和解析xml的工具类

  3      *@ClassName:XmlUtil

  4      *@author: chenyoulong  Email: chen.youlong@payeco.com

  5      *@date :2012-9-29 上午9:51:28

  6      *@Description:TODO

  7      */

  8     public class XmlUtil{

  9         /**

 10          * java 转换成xml

 11          * @Title: toXml

 12          * @Description: TODO

 13          * @param obj 对象实例

 14          * @return String xml字符串

 15          */

 16         public static String toXml(Object obj){

 17             XStream xstream=new XStream();

 18 //            XStream xstream=new XStream(new DomDriver()); //直接用jaxp dom来解释

 19 //            XStream xstream=new XStream(new DomDriver("utf-8")); //指定编码解析器,直接用jaxp dom来解释

 20            

 21             ////如果没有这句,xml中的根元素会是<包.类名>;或者说:注解根本就没生效,所以的元素名就是类的属性

 22             xstream.processAnnotations(obj.getClass()); //通过注解方式的,一定要有这句话

 23             return xstream.toXML(obj);

 24         }

 25         

 26         /**

 27          *  将传入xml文本转换成Java对象

 28          * @Title: toBean

 29          * @Description: TODO

 30          * @param xmlStr

 31          * @param cls  xml对应的class类

 32          * @return T   xml对应的class类的实例对象

 33          *

 34          * 调用的方法实例:PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class);

 35          */

 36         public static <T> T  toBean(String xmlStr,Class<T> cls){

 37             //注意:不是new Xstream(); 否则报错:java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory

 38             XStream xstream=new XStream(new DomDriver());

 39             xstream.processAnnotations(cls);

 40             T obj=(T)xstream.fromXML(xmlStr);

 41             return obj;           

 42         }

 43

 44        /**

 45          * 写到xml文件中去

 46          * @Title: writeXMLFile

 47          * @Description: TODO

 48          * @param obj 对象

 49          * @param absPath 绝对路径

 50          * @param fileName    文件名

 51          * @return boolean

 52          */

 53      

 54         public static boolean toXMLFile(Object obj, String absPath, String fileName ){

 55             String strXml = toXml(obj);

 56             String filePath = absPath + fileName;

 57             File file = new File(filePath);

 58             if(!file.exists()){

 59                 try {

 60                     file.createNewFile();

 61                 } catch (IOException e) {

 62                     log.error("创建{"+ filePath +"}文件失败!!!" + Strings.getStackTrace(e));

 63                     return false ;

 64                 }

 65             }// end if

 66             OutputStream ous = null ;

 67             try {

 68                 ous = new FileOutputStream(file);

 69                 ous.write(strXml.getBytes());

 70                 ous.flush();

 71             } catch (Exception e1) {

 72                 log.error("写{"+ filePath +"}文件失败!!!" + Strings.getStackTrace(e1));

 73                 return false;

 74             }finally{

 75                 if(ous != null )

 76                     try {

 77                         ous.close();

 78                     } catch (IOException e) {

 79                         log.error("写{"+ filePath +"}文件关闭输出流异常!!!" + Strings.getStackTrace(e));

 80                     }

 81             }

 82             return true ;

 83         }

 84        

 85         /**

 86          * 从xml文件读取报文

 87          * @Title: toBeanFromFile

 88          * @Description: TODO

 89          * @param absPath 绝对路径

 90          * @param fileName 文件名

 91          * @param cls

 92          * @throws Exception

 93          * @return T

 94          */

 95         public static <T> T  toBeanFromFile(String absPath, String fileName,Class<T> cls) throws Exception{

 96             String filePath = absPath +fileName;

 97             InputStream ins = null ;

 98             try {

 99                 ins = new FileInputStream(new File(filePath ));

100             } catch (Exception e) {

101                 throw new Exception("读{"+ filePath +"}文件失败!", e);

102             }

103            

104             String encode = useEncode(cls);

105             XStream xstream=new XStream(new DomDriver(encode));

106             xstream.processAnnotations(cls);

107             T obj =null;

108             try {

109                 obj = (T)xstream.fromXML(ins);

110             } catch (Exception e) {

111                 // TODO Auto-generated catch block

112                 throw new Exception("解析{"+ filePath +"}文件失败!",e);

113             }

114             if(ins != null)

115                 ins.close();

116             return obj;           

117         }

118        

119     }

 

[文件] XStreamTest.rar ~ 11KB    下载(32)

[文件] xpp3_min-1.1.4c.jar ~ 24KB    下载(28)

[文件] xstream-1.4.1.jar ~ 484KB    下载(36)

本文源自:http://www.oschina.net/code/snippet_116183_14202

 

posted @ 2021-07-27 15:32  又见君  阅读(1534)  评论(0)    收藏  举报