文章目录
XStream 是一个用于 Java 的轻量级 XML 序列化库,它允许你将 Java 对象序列化为 XML 文档,或将 XML 文档反序列化为 Java 对象。XStream 的使用非常直观且简单,但它也提供了足够的灵活性来自定义序列化行为。
XStream 的基本使用步骤
-
导入依赖:
如果你在使用 Maven,可以在pom.xml
文件中添加以下依赖:<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.18</version> <!-- 使用最新版本 --> </dependency>
-
创建 XStream 实例:
创建一个XStream
实例对象,通常情况下你可以直接创建一个实例,但在生产环境中,为了性能考虑,建议复用实例而不是每次都新建。import com.thoughtworks.xstream.XStream; public class XStreamExample { private static final XStream xstream = createXStream(); private static XStream createXStream() { return new XStream(); } }
-
序列化对象为 XML:
使用toXML
方法将 Java 对象转换为 XML 字符串。public class Person { private String name; private int age; // 构造函数、getter 和 setter } public static void main(String[] args) { Person person = new Person(); person.setName("张三"); person.setAge(25); String xml = xstream.toXML(person); System.out.println(xml); }
-
从 XML 反序列化为对象:
使用fromXML
方法将 XML 字符串转换为 Java 对象。public static void main(String[] args) { String xml = "<person><name>张三</name><age>25</age></person>"; Person person = (Person) xstream.fromXML(xml); System.out.println(person.getName() + ", " + person.getAge()); }
高级用法
自定义别名
XStream 允许你为类指定别名,这样生成的 XML 将更加简洁。
xstream.alias("person", Person.class);
忽略某些字段
如果不想序列化某个字段,可以使用 omitField
方法。
xstream.omitField(Person.class, "age");
自定义转换器
XStream 允许你为特定类型提供自定义的转换器。
xstream.registerConverter(new MyCustomConverter());
类型安全
默认情况下,XStream 允许任何类型的对象被反序列化,这可能会带来安全隐患。可以通过设置信任的类列表来限制反序列化的对象类型。
xstream.addPermission(AnyTypePermission.NONE);
xstream.addPermission(ClassPermission.SAFE);
xstream.addPermission(new WildcardTypePermission(new String[]{"com.example.*"}));
示例
下面是一个完整的示例,展示如何使用 XStream 序列化和反序列化一个简单的 Person
类。
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
public class XStreamExample {
public static void main(String[] args) {
XStream xstream = new XStream(new DomDriver());
xstream.alias("person", Person.class); // 设置别名
// 创建一个 Person 对象
Person person = new Person();
person.setName("张三");
person.setAge(25);
// 序列化为 XML
String xml = xstream.toXML(person);
System.out.println(xml);
// 从 XML 反序列化为 Person 对象
Person deserializedPerson = (Person) xstream.fromXML(xml);
System.out.println(deserializedPerson.getName() + ", " + deserializedPerson.getAge());
}
}
class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
XStream常见注解
虽然 XStream 本身并不直接支持标准的 Java 注解,但有一些库和方法可以帮助你使用注解来控制序列化过程。其中最流行的库之一是 JAnnotate-XStream
,它扩展了 XStream 并提供了对注解的支持。以下是一些常用的注解及其用途:
XStream 是一个用于 Java 的轻量级 XML 序列化库,它可以将 Java 对象序列化为 XML 文档,或将 XML 文档反序列化为 Java 对象。虽然 XStream 本身不直接支持 Java 注解,但你可以使用第三方库 JAnnotate-XStream
来支持注解。
安装 JAnnotate-XStream
首先,你需要在项目中添加 JAnnotate-XStream 的依赖。如果你使用 Maven,可以在 pom.xml
文件中添加如下依赖:
<dependency>
<groupId>de.janert.oggv.xstream</groupId>
<artifactId>jannotate-xstream</artifactId>
<version>1.4.10</version>
</dependency>
使用 JAnnotate-XStream 注解
JAnnotate-XStream 提供了一系列注解来控制序列化和反序列化的行为。以下是一些常用的注解及其用途:
1. @XStreamAlias
- 用途:为类或字段定义一个 XML 元素的别名。
- 示例:
@XStreamAlias("person") public class Person { @XStreamAlias("name") private String name; private int age; // 构造函数、getter 和 setter }
2. @XStreamAsAttribute
- 用途:将字段作为 XML 属性输出,而不是作为一个单独的 XML 元素。
- 示例:
@XStreamAlias("person") public class Person { @XStreamAlias("name") private String name; @XStreamAsAttribute private int age; // 构造函数、getter 和 setter }
3. @XStreamOmitField
- 用途:忽略某个字段,使其不参与序列化过程。
- 示例:
@XStreamAlias("person") public class Person { @XStreamAlias("name") private String name; @XStreamOmitField private int age; // 构造函数、getter 和 setter }
4. @XStreamConverter
- 用途:指定自定义的转换器,用于特定类型的序列化和反序列化。
- 示例:
@XStreamAlias("person") public class Person { @XStreamAlias("name") private String name; @XStreamConverter(MyCustomConverter.class) private int age; // 构造函数、getter 和 setter }
5. @XStreamImplicit
- 用途:隐式地将集合类型转换为 XML 元素列表。
- 示例:
@XStreamAlias("person") public class Person { @XStreamAlias("name") private String name; @XStreamImplicit(itemFieldName = "item") private List<String> items; // 构造函数、getter 和 setter }
示例代码
下面是一个完整的示例,展示如何使用 JAnnotate-XStream 的注解来控制序列化和反序列化过程:
import com.thoughtworks.xstream.XStream;
import de.janert.oggv.xstream.annotations.XStreamAlias;
import de.janert.oggv.xstream.annotations.XStreamAsAttribute;
import de.janert.oggv.xstream.annotations.XStreamOmitField;
import de.janert.oggv.xstream.annotations.XStreamSetupProcessor;
import de.janert.oggv.xstream.annotations.processors.JAnnotateXStreamSetupProcessor;
public class Main {
public static void main(String[] args) {
XStream xstream = new XStream();
xstream.setupProcessor(new JAnnotateXStreamSetupProcessor()); // 启用注解支持
Person person = new Person();
person.setName("张三");
person.setAge(25);
person.addItem("item1");
person.addItem("item2");
String xml = xstream.toXML(person);
System.out.println(xml);
Person deserializedPerson = (Person) xstream.fromXML(xml);
System.out.println(deserializedPerson.getName() + ", " + deserializedPerson.getAge());
}
}
@XStreamAlias("person")
class Person {
@XStreamAlias("name")
private String name;
@XStreamAsAttribute
private int age;
@XStreamImplicit(itemFieldName = "item")
private List<String> items;
public Person() {
items = new ArrayList<>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void addItem(String item) {
items.add(item);
}
}
在这个示例中,我们定义了一个 Person
类,并使用了 @XStreamAlias
、@XStreamAsAttribute
和 @XStreamImplicit
注解来控制序列化过程。通过 JAnnotateXStreamSetupProcessor
处理器,XStream 能够识别这些注解并按照注解配置进行序列化和反序列化。
使用 XStream 没有注解的情况
如果你不想使用注解,或者希望手动配置 XStream,可以通过编程方式来设置别名、忽略字段等:
XStream xstream = new XStream();
xstream.alias("person", Person.class);
xstream.aliasField("name", Person.class, "name");
xstream.useAttributeFor(Person.class, "age");
xstream.ignoreField(Person.class, "items");
自定义转换器
如果你需要更细粒度的控制,可以自定义转换器。例如,创建一个自定义转换器来处理日期类型:
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.util.Date;
public class CustomDateConverter implements Converter {
@Override
public boolean canConvert(Class<?> type) {
return Date.class.isAssignableFrom(type);
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
Date date = (Date) source;
writer.setValue(date.toString());
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
String dateString = reader.getValue();
try {
return new SimpleDateFormat("yyyy-MM-dd").parse(dateString);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
然后在 XStream 实例中注册这个转换器:
XStream xstream = new XStream();
xstream.registerConverter(new CustomDateConverter());
总结
通过使用 JAnnotate-XStream,你可以方便地利用注解来控制 XStream 的序列化和反序列化行为。这些注解提供了丰富的配置选项,使得 XML 与 Java 对象之间的映射更加灵活和强大。同时,你还可以通过编程方式来配置 XStream,或者自定义转换器以满足特定需求。