XStream概述
官网: http://x-stream.github.io/index.html
XStream开源类库,用于将java对象序列化为XML或者将XML反序列化为Java对象,是Java对象和XML之间的一个双向转换器.
目前最新的版本是1.4.10 . May 23, 2017 XStream 1.4.10 released
XStream的特点
- 灵活易用:提供简单、灵活、易用的统一接口,用户无需了解底层细节
- 无需映射:大多数对象都可以在无须映射的情况下进行序列化以及反序列化的操作
- 高速稳定:解析速度快,占用内存少
- 灵活转换:转换策略都是可以定制的,允许自定义类型存储为指定的XML格式
- 易于集成:通过实现特定的接口,可以直接和其他任何树形结构进行序列化与反序列化操作
等等…… 具体参见官网说明
XStream架构
Converters 转换器
当XStream遇到需要转换的对象时,它会委派给合适的转换器实现。 XStream为通用类型提供了多种转换器实现,包括基本数据类型、String、Collections、Arrays、null、Date等。
I/O 输入输出
XStream是通过接口HierarchicalStreamWriter和HierachialStreamReader从底层XML数据中抽象而来的,分别用于序列化和反序列化操作。
Context 上下文引用
在XStream序列化或者反序列化对象时,它会创建两个类MarshallingContext和UnmarshallingContext, 由他们来处理数据并委派合适的转换器。 XStream提供了三种上下文的默认实现。
区别如下:
XStream.XPATH_REFERENCES(默认值)通过XPath引用来标识重复的引用
XStream.ID_REFERENCES :使用ID应用来标识重复的引用
XStream.NO_REFERENCES:对象作为树形结构,重复的引用被视为两个不同的对象,循环引用会导致异常产生。这种模式速度快,占用内存少。
可以通过XStream.setMode()方法调整。
Facade 统一接口
作为XStream的统一入口点,它将上面所提到的重要组件集成在一起,以统一的接口开放出来
Quick Start
加入Maven依赖
...... <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>${xstream.version}</version> </dependency> ..... <xstream.version>1.4.10</xstream.version>
接下来,开始我们的XStream之旅,对象和XML之间的互换。
Domain实体类
先准备两个Domain类
package com.xgj.oxm.xstream.quickDemo.domain; import java.io.Serializable; import java.util.Date; public class LoginLog implements Serializable { private static final long serialVersionUID = 1L; private int loginLogId; private int userId; private String ip; private Date loginDate; public int getLoginLogId() { return loginLogId; } public void setLoginLogId(int loginLogId) { this.loginLogId = loginLogId; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public Date getLoginDate() { return loginDate; } public void setLoginDate(Date loginDate) { this.loginDate = loginDate; } }
package com.xgj.oxm.xstream.quickDemo.domain; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; public class User implements Serializable { private static final long serialVersionUID = 1L; private int id; private String userName; private String password; private int credits; private String lastIp; private Date lastVisit; private List<LoginLog> logs; private Map datas; public List<LoginLog> getLogs() { return logs; } public void setLogs(List logs) { this.logs = logs; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getCredits() { return credits; } public void setCredits(int credits) { this.credits = credits; } public String getLastIp() { return lastIp; } public void setLastIp(String lastIp) { this.lastIp = lastIp; } public Date getLastVisit() { return lastVisit; } public void setLastVisit(Date lastVisit) { this.lastVisit = lastVisit; } public void addLoginLog(LoginLog log) { if (this.logs == null) { logs = new ArrayList<LoginLog>(); } logs.add(log); } public Map getDatas() { return datas; } public void setDatas(Map datas) { this.datas = datas; } }
XML和Object互转
接下来我们来看下是XStream是如何进行转换的
package com.xgj.oxm.xstream.quickDemo; import java.io.FileInputStream; import java.io.FileOutputStream; import java.text.ParseException; import java.util.Date; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; import com.xgj.oxm.xstream.quickDemo.domain.LoginLog; import com.xgj.oxm.xstream.quickDemo.domain.User; public class XStreamDemo { private static XStream xstream; static { // 创建一个Xstream实例,并指定一个XML解析器 xstream = new XStream(new DomDriver()); } /** * * * @Title: getUser * * @Description: 初始化转换对象 * * @return * * @return: User * @throws ParseException */ public static User getUser() throws ParseException { LoginLog log = new LoginLog(); log.setIp("127.0.0.1"); log.setLoginLogId(99); log.setUserId(1); log.setLoginDate(new Date()); User user = new User(); user.setId(1); user.setUserName("Artisan"); user.setPassword("artisan"); user.setCredits(1000); user.setLastVisit(new Date()); user.addLoginLog(log); return user; } /** * * * @Title: objectToXml * * @Description: Java对象转换成XML * * @throws Exception * * @return: void */ public static void objectToXml() throws Exception { // 获取转换的User对象实例 User user = getUser(); // 输出内容到控制台,查看一下 System.out.println(xstream.toXML(user)); // 实例化一个文件输出流 FileOutputStream os = new FileOutputStream("D://XstreamDemo.xml"); // 将User对象转换为XML,并保存到指定的文件 xstream.toXML(user, os); System.out.println("objectToXml successfully"); } /** * * * @Title: XmlToObject * * @Description: Xml转Java对象 * * @throws Exception * * @return: void */ public static void XmlToObject() throws Exception { // 实例化文件输入流 FileInputStream in = new FileInputStream("D://XstreamDemo.xml"); // 将xml文件输入流转化为对象 User user = (User) xstream.fromXML(in); // 遍历 for (LoginLog log : user.getLogs()) { System.out.println("访问时间:" + log.getLoginDate()); System.out.println("访问IP:" + log.getIp()); } } public static void main(String[] args) throws Exception { objectToXml(); System.out.println("====================================="); XmlToObject(); } }
我们来看下生成的XML
<com.xgj.oxm.xstream.quickDemo.domain.User> <id>1</id> <userName>Artisan</userName> <password>artisan</password> <credits>1000</credits> <lastVisit>2017-12-05 07:30:46.772 UTC</lastVisit> <logs> <com.xgj.oxm.xstream.quickDemo.domain.LoginLog> <loginLogId>99</loginLogId> <userId>1</userId> <ip>127.0.0.1</ip> <loginDate>2017-12-05 07:30:46.772 UTC</loginDate> </com.xgj.oxm.xstream.quickDemo.domain.LoginLog> </logs> </com.xgj.oxm.xstream.quickDemo.domain.User>
小结
我们在实例化Xstream的时候,指定了一个Dom XML解析器
xstream = new XStream(new DomDriver());
如果不指定,默认为XPP(XML Pull Parser),一种高速解析XML文件的方式,速度比传统方式快很多 。
- object to XML 使用xstream.toXML方法
- XML back to an object 使用 xstream.fromXML方法
示例源码
代码已托管到Github—> https://github.com/yangshangwei/SpringMaster