XML处理利器:XStream
2016-02-24 18:00
162 查看
在项目中进行一些类似黑名单、白名单的配置时,需要多个文本文件,很麻烦。本文要通过XStream实现一个XML文件,配置多个功能。本文主要参考《Spring 3.X 企业应用开发实战》第14章内容,加了一下自己的理解,自己的应用。
1 Converters(转换器)
java对象中有可能有int,float,String,Array,Collection等数据类型的成员变量,这些数据类型如何序列到XML文件中,以及如何从XML文件中反序列化回来,这时就需要Converters。
2 IO(输入输出)
有文件操作就有IO。XStream通过HierarchicalStreamWriter和HierarchicalStreamReader两个接口实现序列化和反序列化。
3 Context(上下文引用)
XStream在进行序列化和反序列化时会创建两个对象,MarshallingContext(编组上下文,实现java对象到XML)和UnmarshallingContext(反编组上下文,实现XML到java对象),由他们来处理数据并委派给合适的Converters转换器。
4 Facade(统一入口)
XStream通过Facade将上面的3个重要组件集成在一起,以统一的接口开放出来。
在默认情况下,Java对象到XML的映射,java类全名(包括包名)对应XML的根元素名字,java类的属性名对应XML的元素名。例如:
User.java
则其对应的XML为:
这样很繁琐,可以通过下面的代码简化下:
则此时对应的XML为:
2 设置高级别名
还有一种别名叫“类成员作为属性别名”,这里的“属性别名”是只XML的属性别名。如下面的例子:
LoginLog.java
User.java
按照上面的基本别名设置,则对应的XML如下所示:
上面的XML较为繁琐,能否简化成下面的形式呢?
要实现上面的简化,需要做的是:
XStream概述
XStream是一套简洁易用的开源框架,用于将java对象序列化为XML文件或者XML文件反序列化为java对象,是java对象和XML相互转换的利器。XStream框架
XStream主要由Converters,IO,Context,Facade四部分组成。1 Converters(转换器)
java对象中有可能有int,float,String,Array,Collection等数据类型的成员变量,这些数据类型如何序列到XML文件中,以及如何从XML文件中反序列化回来,这时就需要Converters。
2 IO(输入输出)
有文件操作就有IO。XStream通过HierarchicalStreamWriter和HierarchicalStreamReader两个接口实现序列化和反序列化。
3 Context(上下文引用)
XStream在进行序列化和反序列化时会创建两个对象,MarshallingContext(编组上下文,实现java对象到XML)和UnmarshallingContext(反编组上下文,实现XML到java对象),由他们来处理数据并委派给合适的Converters转换器。
4 Facade(统一入口)
XStream通过Facade将上面的3个重要组件集成在一起,以统一的接口开放出来。
Demo
XmlParserTest.javapackage org.fan.test.xstream; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; import java.io.FileInputStream; import java.io.FileNotFoundException; /** * Created by fan on 16-1-27. */ public class XmlParserTest { XStream xStream = new XStream(new DomDriver()); TypeConfigList typeConfigList; public static void main(String[] args) { final XmlParser xmlParser = new XmlParser(); xmlParser.xStream.alias("TypeConfigs", TypeConfigList.class); xmlParser.xStream.alias("TypeConfig", TypeConfig.class); //typeConfigList是TypeConfigList.java中的成员变量名 xmlParser.xStream.addImplicitCollection(TypeConfigList.class, "typeConfigList"); xmlParser.readConfigFile(); System.out.println("YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"); } public void readConfigFile() { String path = XmlParser.class.getResource("/").getPath(); FileInputStream pusherInputStream = null; try { pusherInputStream = new FileInputStream(path + "config.xml"); } catch (FileNotFoundException e) { e.printStackTrace(); } typeConfigList = (TypeConfigList) xStream.fromXML(pusherInputStream); for (TypeConfig typeConfig : typeConfigList.getTypeConfigList()) { long[] datas = typeConfig.getDatas(); for (int i = 0; i < datas.length; i++) { System.out.println(datas[i]); } } } }
设置别名
1 设置基本别名在默认情况下,Java对象到XML的映射,java类全名(包括包名)对应XML的根元素名字,java类的属性名对应XML的元素名。例如:
User.java
package org.fan.test.xstream; /** * Created by fan on 16-2-24. */ public class User { private int userId; private String userName; }
则其对应的XML为:
<?xml version="1.0" encoding="UTF-8"?> <org.fan.test.xstream.User> <userId>1</userId> <userName>fan</userName> </org.fan.test.xstream.User>
这样很繁琐,可以通过下面的代码简化下:
XStream xStream = new XStream(new DomDriver()); xStream.alias("user", User.class); xStream.aliasField("id", User.class, "userId"); xStream.aliasField("name", User.class, "userName");
则此时对应的XML为:
<?xml version="1.0" encoding="UTF-8"?> <User> <id>1</id> <name>fan</name> </User>
2 设置高级别名
还有一种别名叫“类成员作为属性别名”,这里的“属性别名”是只XML的属性别名。如下面的例子:
LoginLog.java
package org.fan.test.xstream; /** * Created by fan on 16-2-24. */ public class LoginLog { private int logId; private String ip; }
User.java
package org.fan.test.xstream; import java.util.List; /** * Created by fan on 16-2-24. */ public class User { private int userId; private String userName; private List<LoginLog> logs; }
XStream xStream = new XStream(new DomDriver()); xStream.alias("user", User.class); xStream.aliasField("id", User.class, "userId"); xStream.aliasField("name", User.class, "userName");
xStream.alias("loginLog", LoninLog.class);
xStream.aliasField("id", LoginLog.class, "logId");
按照上面的基本别名设置,则对应的XML如下所示:
<User> <id>1</id> <name>fan</name> <loginLogs> <loginLog> <id>0</id> <ip>192.168.1.10</ip> </loginLog> <loginLog> <id>1</id> <ip>192.168.1.101</ip> </loginLog> </loginLogs> </User>
上面的XML较为繁琐,能否简化成下面的形式呢?
<User> <id>1</id> <name>fan</name> <loginLog id="0"> <ip>192.168.1.10</ip> </loginLog> <loginLog id="1"> <ip>192.168.1.101</ip> </loginLog> </User>
要实现上面的简化,需要做的是:
//把LoginLog的logId属性视为XML属性 xStream.aliasAttribute(LoginLog.class, "logId", "id"); xStream.useAttributeFor(LoginLog.class, "logId"); //隐藏集合类型的XML父节点,即忽略XML中的<logs></logs>标记。其中"logs"是User的属性名 xStream.addImplicitCollection(User.class, "logs")
配置文件
<?xml version="1.0" encoding="UTF-8"?> <TypeConfigs> <TypeConfig> <type>1</type> <datas> <long>123</long> <long>321</long> <long>44444</long> </datas> </TypeConfig> <TypeConfig> <type>2</type> <datas> <long>7777</long> <long>88888845</long> <long>99999</long> </datas> </TypeConfig> </TypeConfigs>
运行结果
相关文章推荐
- Lua中的require(二)
- Android之解决太大太多图片造成的oom
- JavaScript 开发进阶:理解 JavaScript 作用域和作用域链
- SDUT-汤圆星の汤圆树
- 经验之谈-记录
- app图标 和 启动页的大小设置
- mysql中文乱码
- 字体大小
- 安卓 Notification 使用方法小结
- WebService学习(1)
- 【推荐】一个强大的html5游戏引擎 pixi
- iframe设置height无效
- Autofc与Mvc,WebForm,Weiapi,Owin整合源码分析
- 6lowpan技术博客收录
- [Lintcode]Product of Array Exclude Itself
- 43.Evaluate the following CREATE SEQUENCE statement:
- mysql 乱码问题
- android 删除文件错误:open failed: EBUSY (Device or resource busy)
- MySQL innodb引擎,事务提交 commit 异常,但数据提交成功
- 配置PowerShell工作流环境(2)