当前位置 博文首页 > 高远的博客:XStream4Java高级应用

    高远的博客:XStream4Java高级应用

    作者:[db:作者] 时间:2021-09-06 22:46

    XStream4Java高级应用

    操作环境

    • jdk1.7
    • myeclipse10.7
    • xstream1.4.8

    需要使用到的包

    • xstream-1.4.8.jar
    • xmlpull-1.1.3.1.jar
    • xpp3_min-1.1.4c.jar

    为什么使用xstream

    Xstream是一种OXMapping 技术,是用来处理XML文件序列化的框架,在将JavaBean序列化,或将XML文件反序列化的时候,不需要其它辅助类和映射文件,使得XML序列化不再繁索。Xstream也可以将JavaBean序列化成Json或反序列化,使用非常方便。简而言之,极大的方便解析xml。

    目标

    • 实现微信文本消息xml和obj之间的相互转换(简单,基本应用)
    • 实现微信图文消息xml和obj之间的相互转换(难,复杂xml的解析应用)

    微信消息原文件

    • 文本消息

      <xml>
      <ToUserName><![CDATA[toUser]]></ToUserName>
      <FromUserName><![CDATA[fromUser]]></FromUserName>
      <CreateTime>12345678</CreateTime>
      <MsgType><![CDATA[text]]></MsgType>
      <Content><![CDATA[你好]]></Content>
      </xml>
      
    • 图文消息

      <xml>
      <ToUserName><![CDATA[toUser]]></ToUserName>
      <FromUserName><![CDATA[fromUser]]></FromUserName>
      <CreateTime>12345678</CreateTime>
      <MsgType><![CDATA[news]]></MsgType>
      <ArticleCount>2</ArticleCount>
      <Articles>
      <item>
      <Title><![CDATA[title1]]></Title> 
      <Description><![CDATA[description1]]></Description>
      <PicUrl><![CDATA[picurl]]></PicUrl>
      <Url><![CDATA[url]]></Url>
      </item>
      <item>
      <Title><![CDATA[title]]></Title>
      <Description><![CDATA[description]]></Description>
      <PicUrl><![CDATA[picurl]]></PicUrl>
      <Url><![CDATA[url]]></Url>
      </item>
      </Articles>
      </xml> 
      

    构建原文件对应bean(重点)

    • 文本消息TextMsg.java(为了练习别名的用法,我们没有按照xml构建相应的字段名)

      public class TextMsg {
          private String toUserName;
          private String fromUserName;
          private String createTime;
          private String msgType;
          private String content;
          private String msgId;
          //Getter、Setter...
      }
      
    • 图文消息PicAndTextMsg.java

      public class PicAndTextMsg {
          private String ToUserName;
          private String FromUserName;
          private String CreateTime;
          private String MsgType;
          private String ArticleCount;
          private List<item> Articles;
          //Getter、Setter...
      
          //特别注意:static
          public static class item {
              private String Title;
              private String Description;
              private String PicUrl;
              private String Url;
              //Getter、Setter...  
          }
      }
      

    转换操作

    • 特意强调了别名的用法,但实际使用中建议按照xml原文件构造对应bean,不然再去设置字段的别名很麻烦。
    • 操作代码
      package com.wgyscsf.test;

      import java.io.File;
      import java.util.ArrayList;
      import java.util.List;
      
      import org.junit.Test;
      
      import com.thoughtworks.xstream.XStream;
      import com.wgyscsf.bean.PicAndTextMsg;
      import com.wgyscsf.bean.PicAndTextMsg.item;
      import com.wgyscsf.bean.TextMsg;
      
      /**
       * @author 高远</n>
       * 编写日期   2016-5-11下午5:06:34</n>
       * 邮箱  wgyscsf@163.com</n>
       * 博客  http://blog.csdn.net/wgyscsf</n>
       * TODO</n>
       */
      /**
       * 目的:我们测试如何使用xstream实现xml和javabean的转换,使用的是xstream较难的部分。
       * 我们实现对源文件向对应javabean的转换以及对应bean向xml文件的转换。 
       * 测试用例:微信文档的关于普通文字消息的原格式文件和图文消息的原格式文件。
       */
      /**
       * 第一个用例:简单的bean对象,实现xml和bean之间的转换。 第二个用例:bean里面包括一个List,list里面还是一个bean.
       */
      public class XStreamTest {
          /*
           * 任务:将xml包下面的textMsg.xml转化为obj
           */
          @Test
          public void xml2Obj() {
      
              File file = new File(this.getClass().getClassLoader().getResource("")
                      .getPath()
                      + "com/wgyscsf/xml/textMsg.xml");// 获取目标文件
              System.out.println(file.getPath());// 测试打印路径
              // 初始化xstream
              XStream xStream = new XStream();
              // 这一句话 的意思是把根节点设置为一个别名:xml,如果不加,显示为:com.wgyscsf.bean.TextMsg。
               xStream.alias("xml", TextMsg.class);
              /*
               * 为字段设置别名。第一个参数就是要显示的参数,第二个参数就是参数所在的bean,第三个参数就是原来的字段。当然,
               * 如果当初构建bean时按照xml的要求设置对应的字段就不需要在设置下面的别名了
               * (我们一般构建bean的时候就是按照目标xml的字段进行命名的,这样就不用设置别名了)。
               */
               xStream.aliasField("ToUserName", TextMsg.class, "toUserName");
               xStream.aliasField("FromUserName", TextMsg.class, "fromUserName");
               xStream.aliasField("CreateTime", TextMsg.class, "createTime");
               xStream.aliasField("MsgType", TextMsg.class, "msgType");
               xStream.aliasField("Content", TextMsg.class, "content");
               xStream.aliasField("MsgId", TextMsg.class, "msgId");
              TextMsg textMsg = (TextMsg) xStream.fromXML(file);
              System.out.println("--->" + textMsg.toString());
          }
      
          /*
           * 任务:将bean转化为xml,显示和xml包下面的textMsg.xml的内容一样格式的内容。
           */
          @Test
          public void obj2Xml() {
              TextMsg textMsg = new TextMsg("toUser", "fromUser", "1348831860",
                      "text", "this is a test", "1234567890123456");// 设置bean参数
              // 初始化xstream
              XStream xStream = new XStream();
              // 这一句话 的意思是把根节点设置为一个别名:xml,如果不加,显示为:com.wgyscsf.bean.TextMsg
              xStream.alias("xml", TextMsg.class);
              /*
               * 为字段设置别名。第一个参数就是要显示的参数,第二个参数就是参数所在的bean,第三个参数就是原来的字段。当然,
               * 如果当初构建bean时按照xml的要求设置对应的字段就不需要在设置下面的别名了
               * (我们一般构建bean的时候就是按照目标xml的字段进行命名的,这样就不用设置别名了)。
               */
              xStream.aliasField("ToUserName", TextMsg.class, "toUserName");
              xStream.aliasField("FromUserName", TextMsg.class, "fromUserName");
              xStream.aliasField("CreateTime", TextMsg.class, "createTime");
              xStream.aliasField("MsgType", TextMsg.class, "msgType");
              xStream.aliasField("Content", TextMsg.class, "content");
              xStream.aliasField("MsgId", TextMsg.class, "msgId");
              String xml = xStream.toXML(textMsg);
              System.out.println(xml);
          }
      
          /*
           * 任务:解析xml包下面的picAndTextMsg.xml
           */
          @Test
          public void xml2List() {
              File file = new File(this.getClass().getClassLoader().getResource("")
                      .getPath()
                      + "com/wgyscsf/xml/picAndTextMsg.xml");
              System.out.println(file.getPath());
              XStream xStream = new XStream();
              /*
               * 这一句话 的意思是把根节点设置为一个别名:xml,如果不加,显示为:com.wgyscsf.bean.TextMsg
               */
              xStream.alias("xml", PicAndTextMsg.class);
              xStream.alias("item", item.class);// 这个内部类也需要设置别名
              PicAndTextMsg picAndTextMsg = (PicAndTextMsg) xStream.fromXML(file);// 开始转化
              System.out.println("--->" + picAndTextMsg.toString());
          }
      
          /*
           * 任务:设置PicAndTextMsg,构造出和xml/picAndTextMsg.xml内容一致的xml。
           */
          // 特别注意,内部类item要设置为静态的。
          @Test
          public void list2Xml() {
              // 初始化图文消息bean
              PicAndTextMsg picAndTextMsg = new PicAndTextMsg();
              // 设置图文消息内容
              item i1 = new item();
              i1.setTitle("我是图文消息1");
              i1.setDescription("我是图文消息描述1");
              i1.setPicUrl("我是图文消息图片的地址1");
              i1.setUrl("我是图文消息的地址1");
              item i2 = new item();
              i2.setTitle("我是图文消息2");
              i2.setDescription("我是图文消息描述2");
              i2.setPicUrl("我是图文消息图片的地址2");
              i2.setUrl("我是图文消息的地址2");
              item i3 = new item();
              i3.setTitle("我是图文消息3");
              i3.setDescription("我是图文消息描述3");
              i3.setPicUrl("我是图文消息图片的地址3");
              i3.setUrl("我是图文消息的地址3");
              // 将上述的图文消息加入list
              List<item> itemList = new ArrayList<item>();
              itemList.add(i1);
              itemList.add(i2);
              itemList.add(i3);
              // 设置PicAndTextMsg内容
              picAndTextMsg.setToUserName("这个消息接收者");
              picAndTextMsg.setFromUserName("这个消息发送者");
              picAndTextMsg.setCreateTime("这个消息的创建时间");
              picAndTextMsg.setArticleCount("消息的条数:" + itemList.size());
              picAndTextMsg.setArticles(itemList);
      
              // 开始解析
              XStream xStream = new XStream();
              String xml = xStream.toXML(picAndTextMsg);
              System.out.println("设置别名之前:\n" + xml);
              // 设置别名
              xStream.alias("xml", PicAndTextMsg.class);
              xStream.alias("item", item.class);
              String xml2 = xStream.toXML(picAndTextMsg);
              System.out.println("设置别名之后:\n" + xml2);
      
          }
      }
      

    操作源码

    http://download.csdn.net/detail/wgyscsf/9517082

    cs