在项目中进行一些类似黑名单、白名单的配置时,需要多个文本文件,很麻烦。本文要通过XStream实现一个XML文件,配置多个功能。本文主要参考《Spring 3.X 企业应用开发实战》第14章内容,加了一下自己的理解,自己的应用。
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.java
- package 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","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","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>
要实现上面的简化,需要做的是:
配置文件
- <?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>