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

来源:互联网 发布:java导入自己的package 编辑:程序博客网 时间:2024/05/26 19:18

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:4710  *@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和getter34 }
复制代码
  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和getter13     }
复制代码
  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函数示例1:toxml
复制代码
 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 stub21         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对象转换成xml57         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函数示例2:toBean
复制代码
 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 block112                 throw new Exception("解析{"+ filePath +"}文件失败!",e);113             }114             if(ins != null)115                 ins.close();116             return obj;            117         } 118         119     }