官网: http://x-stream.github.io/
引用官网的话:
XStream是一个简单的库,用于将对象序列化为XML并再次返回。
特征:
便于使用。提供高级外观,简化了常见用例。
不需要映射。大多数对象都可以序列化,而无需指定映射。
性能。速度和低内存占用是设计的关键部分,使其适用于具有高消息吞吐量的大型对象图或系统。
清洁XML。没有重复的信息可以通过反射获得。这导致XML更容易为人类阅读,并且比本机Java序列化更紧凑。
不需要修改对象。序列化内部字段,包括私有和最终字段。支持非公开和内部类。类不需要具有默认构造函数。
完整对象图支持。将维护在对象模型中遇到的重复引用。支持循环引用。
与其他XML API集成。通过实现接口,XStream可以直接与任何树结构(不仅仅是XML)进行序列化。
可定制的转换策略。可以注册策略,允许自定义特定类型如何表示为XML。
安全框架。对未编组类型进行精细控制,以防止受操纵输入的安全问题。
错误消息。当由于格式错误的XML而发生异常时,会提供详细的诊断信息以帮助隔离和修复问题。
替代输出格式。模块化设计允许其他输出格式。XStream目前提供JSON支持和变形。
学习笔记:
依赖:
<!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
将对象序列化为XML
实体类:
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午1:33:09
*
*/
package com.lcf.entity;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午1:33:09
*
*/
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private String name;
private String sex;
private String phone;
private String email;
private int age;
private Date birthday;
private Trait trait;
}
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午1:40:55
*
*/
package com.lcf.entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午1:40:55
*
*/
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Trait {
private String address;
private String contry;
private String city;
}
测试类:
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午1:04:47
*
*/
package com.lcf.test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import org.junit.Test;
import com.lcf.entity.ClassAndGrade;
import com.lcf.entity.Student;
import com.lcf.entity.Trait;
import com.lcf.entity.User;
import com.thoughtworks.xstream.XStream;
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午1:04:47
*
* 参考网址:http://x-stream.github.io/
*/
public class Demo1 {
private static XStream xStream = new XStream();// 获取XStream对象
static {
// 自定义类名创建别名到XML元素名称,可选--->但XML元素名称将包含每个类(包括包)的完全限定名称
xStream.alias(\"user\", User.class);
xStream.alias(\"trait\", Trait.class);//类别名
xStream.aliasField(\"username\", User.class, \"name\");//属性别名 第一个参数为修改之后的名称,第三个参数为修改之前的名称
}
/*
* 将对象序列化为XML
*/
@Test
public void method1() {
// 设置对象属性
User user = new User(\"海王\", \"男\", \"12345678901\", \"123@.com\", 1000, new Date(), new Trait(\"地球\", \"亚特兰蒂斯\", \"水城\"));
// 生成xml
String xml = xStream.toXML(user);
System.out.println(xml);
/*<user>
<username>海王</username>
<sex>男</sex>
<phone>12345678901</phone>
<email>123@.com</email>
<age>1000</age>
<birthday>2018-12-21 05:53:54.153 UTC</birthday>
<trait>
<address>地球</address>
<contry>亚特兰蒂斯</contry>
<city>水</city>
</trait>
</user>*/
}
}
从XML反序列化对象
/*
* 从XML反序列化对象
*/
@Test
public void method2() {
String xml = \"<user>\\r\\n\" +
\" <name>海王</name>\\r\\n\" +
\" <sex>男</sex>\\r\\n\" +
\" <phone>12345678901</phone>\\r\\n\" +
\" <email>123@.com</email>\\r\\n\" +
\" <age>1000</age>\\r\\n\" +
\" <birthday>2018-12-21 05:53:54.153 UTC</birthday>\\r\\n\" +
\" <trait>\\r\\n\" +
\" <address>地球</address>\\r\\n\" +
\" <contry>亚特兰蒂斯</contry>\\r\\n\" +
\" <city>水</city>\\r\\n\" +
\" </trait>\\r\\n\" +
\" </user>\";
User u = (User) xStream.fromXML(xml);
System.out.println(u.toString());
//输出: User(name=海王, sex=男, phone=12345678901, email=123@.com, age=1000, birthday=Fri Dec 21 13:53:54 CST 2018, trait=Trait(address=地球, contry=亚特兰蒂斯, city=水))
}
注解的使用
实体类:
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午3:02:33
*
*/
package com.lcf.entity;
import java.util.ArrayList;
import java.util.List;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午3:02:33
*
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@XStreamAlias(\"class\")
public class ClassAndGrade {
@XStreamAlias(\"c_name\")
private String cName;
@XStreamAsAttribute // 输出到父类节点 --->等同于xstream.useAttributeFor(ClassAndGrade.class, \"c_no\")
@XStreamAlias(\"c_no\") // 这两个注解可以同时使用
private String cNo;
//@XStreamImplicit // 添加此注解会去除此集合节点,只显示其内容节点
private List<Student> stus = new ArrayList<Student>();
}
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午2:58:19
*
*/
package com.lcf.entity;
import java.util.Date;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/**
* @author : lichenfei
* @date : 2018年12月21日
* @time : 下午2:58:19
*
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@XStreamAlias(\"Student\")
public class Student {
@XStreamOmitField //生成xml时会忽略此属性
private int id;
@XStreamAlias(\"Name\")
private String name;
@XStreamAlias(\"Age\")
private int age;
@XStreamAlias(\"Birthday\")
private Date birthday;
}
测试类:
/*
* 注解的使用
*/
@Test
public void method3() {
XStream xStream = new XStream();//重新实例化对象
xStream.autodetectAnnotations(true);//开启注解扫描,不添加不会起作用,会以默认的方式生成
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student(1,\"张三\", 12, new Date()));
list.add(new Student(2,\"李四\", 15, new Date()));
ClassAndGrade cag = new ClassAndGrade(\"3班\", \"3\", list);
//转换:
String xml = xStream.toXML(cag);
System.out.println(xml);
/*<class c__no=\"3\">
<c__name>3班</c__name>
<stus>
<Student>
<Name>张三</Name>
<Age>12</Age>
<Birthday>2018-12-21 07:37:09.723 UTC</Birthday>
</Student>
<Student>
<Name>李四</Name>
<Age>15</Age>
<Birthday>2018-12-21 07:37:09.723 UTC</Birthday>
</Student>
</stus>
</class>*/
}
生成/读取xml文件:
/*
* 生成xml文件
*/
@Test
public void method4() throws FileNotFoundException {
XStream xStream = new XStream();//重新实例化对象
xStream.autodetectAnnotations(true);//开启注解扫描,不添加不会起作用,会以默认的方式生成
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student(1,\"张三\", 12, new Date()));
list.add(new Student(2,\"李四\", 15, new Date()));
ClassAndGrade cag = new ClassAndGrade(\"3班\", \"3\", list);
//复制method3的方法生成实体类属性
String path = \"src/test/resources/file\";
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
FileOutputStream out = new FileOutputStream(path+\"/\"+\"test_xml.xml\");
xStream.toXML(cag, out);
}
/*
* 读取xml文件
*/
@Test
public void method5() {
XStream xs = new XStream();
xs.processAnnotations(ClassAndGrade.class);//开启注解,必须开启,否则无法进行读取
xs.processAnnotations(Student.class);
ClassAndGrade cag = (ClassAndGrade) xs.fromXML(new File(\"src/test/resources/file/test_xml.xml\"));//这里讲上一个方法的文件地址放进来进行读取
System.out.println(cag.toString());
//输出 : ClassAndGrade(cName=3班, cNo=3, stus=[Student(id=0, name=张三, age=12, birthday=Fri Dec 21 16:00:01 CST 2018), Student(id=0, name=李四, age=15, birthday=Fri Dec 21 16:00:01 CST 2018)])
}
完毕:
版权声明
本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。



