Xstream 简明教程

Xstream - Quick Guide

XStream - Overview

XStream 是一个简单的基于 Java 的库,用于将 Java 对象序列化为 XML,反之亦然。

Features

  1. Easy to use - XStream API 提供了一个高级外观来简化常见的用例。

  2. No need to create mapping - XStream API 为大多数要序列化的对象提供默认映射。

  3. Performance - XStream 速度快且内存占用少,适用于大型对象图或系统。

  4. Clean XML - XStream 产生易于阅读的干净且紧凑的 XML 输出。

  5. Object modification not required - XStream 序列化私有和最终字段等内部字段,并支持非公共和内部类。默认构造函数不是强制要求。

  6. Full object graph support - XStream 允许维护对象模型中遇到的重复引用,还支持循环引用。

  7. Customizable conversion strategies - 可以注册自定义策略,以允许将特定类型自定义表示为 XML。

  8. Security framework - XStream 提供对未编组类型相当程度的可控性,以防止因输入被操纵而出现安全问题。

  9. Error messages - 当由于 XML 格式错误而发生异常时,它提供详细的诊断信息来解决问题。

  10. Alternative output format - XStream 支持其他输出格式,如 JSON 和变形。

Common Uses

  1. Transport − XML 是对象的文本表示,可以用来在独立于序列号/反序列化技术的情况下通过有线传送对象。

  2. Persistence − 对象可以作为 XML 形式保存在数据库中,并在需要时进行编组/解编组。

  3. Configuration − XML 具有自解释性,并且被大量应用于定义配置。对象也可以在转换为 XML 表示后用于配置目的。

  4. Unit Tests − XStream API 与 JUnit 兼容,并且可用于增强应用程序模块的单元测试。

XStream - Environment Setup

在本章,我们将讨论为 Java 设置宜人环境的事物的不同方面。

Local Environment Setup

如果您想为 Java 编程语言设置您的环境,那么本部分将说明如何在计算机上下载和设置 Java。请按照下列步骤设置您的 Java 环境。

Java SE 可以从此链接免费下载:

按照说明下载 Java 并运行 .exe 以在计算机上安装 Java。在您的计算机上安装 Java 后,您需要设置环境变量来指向正确的安装目录:

Setting Up the Path for Windows 2000/XP

假设你已将 Java 安装在 c:\Program Files\java\jdk 目录中 −

  1. 右键单击“我的电脑”,然后选择“属性”。

  2. 点击“高级”标签下的“环境变量”按钮。

  3. 更改“路径”变量,使其也包含 Java 可执行文件路径。例如,如果路径当前设置为“C:\WINDOWS\SYSTEM32”,那么将您的路径更改为“C:\WINDOWS\SYSTEM32;c:\Program Files\java\jdk\bin”。

Setting Up the Path for Windows 95/98/ME

假设你已将 Java 安装在 c:\Program Files\java\jdk 目录中 −

  1. 编辑“C:\autoexec.bat”文件,并在末尾添加以下行:- 'SET PATH = %PATH%;C:\Program Files\java\jdk\bin'

Setting Up the Path for Linux, UNIX, Solaris, FreeBSD

环境变量 PATH 应设置为指向已安装 Java 二进制文件的位置。如果你在这方面遇到问题,请参阅 shell 文档。

例如,如果你使用 bash 作为 shell,则需要在“‘.bashrc: export PATH=/path/to/java:$PATH’”的末尾添加以下行

要编写 Java 程序,您需要一个文本编辑器。市场上有更加复杂的 IDE。但是现在,您可以考虑以下一项:

  1. Notepad − 在 Windows 上,您可以使用任何简单的文本编辑器,如记事本(推荐用于此教程)或 TextPad。

  2. Netbeans − 它是一个免费的 Java IDE,可以从 https://www.netbeans.org/index.html 下载。

  3. Eclipse - 它也是一款由 Eclipse 开源社区开发的 Java IDE,可以从 https://www.eclipse.org/ 下载。

Download XStream Archive

XStream download page 下载 XStream jar 文件的最新版本。在本教程的编写时,我们已经下载了 xstream-1.4.18.jar 并将其复制到 C:\>XStream 文件夹。

OS

Archive name

Windows

xstream-1.4.18.jar

Linux

xstream-1.4.18.jar

Mac

xstream-1.4.18.jar

Set XStream Environment

设置 XStream_HOME 环境变量,以指向存储在计算机上的 xstream jar 的基本目录位置。以下表格显示了如何在 Windows、Linux 和 Mac 上设置 XStream 环境,假设我们在 XStream 文件夹中解压了 xstream-1.4.18.jar。

Sr.No.

OS & Description

1

Windows 将环境变量 XStream_HOME 设置为 C:\XStream

2

Linux export XStream_HOME=/usr/local/XStream

3

Mac export XStream_HOME=/Library/XStream

Set CLASSPATH Variable

设置 CLASSPATH 环境变量来指向 XStream jar 位置。以下表格演示了如何在 Windows、Linux 和 Mac 系统上设置 CLASSPATH 变量,假设我们已将 xstream-1.4.18.jar 存储在 XStream 文件夹中。

Sr.No.

OS & Description

1

Windows 将环境变量 CLASSPATH 设置为 %CLASSPATH%;%XStream_HOME%\xstream-1.4.18.jar;

2

Linux export CLASSPATH=$CLASSPATH:$XStream_HOME/xstream-1.4.18.jar;

3

Mac export CLASSPATH=$CLASSPATH:$XStream_HOME/xstream-1.4.18.jar;

XStream - First Application

在深入了解 XStream 库之前,让我们看一个应用程序的实际使用情况。在此示例中,我们创建了 Student 和 Address 类。我们将创建一个学生对象,然后将其序列化为 XML 字符串。然后对相同的 XML 字符串进行反序列化,以获取回学生对象。

在 C:\>XStream_WORKSPACE 中创建一个名为 XStreamTester 的 java 类文件。

File: XStreamTester.java

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamTester {

   public static void main(String args[]) {
      XStreamTester tester = new XStreamTester();
      XStream xstream = new XStream(new StaxDriver());

      Student student = tester.getStudentDetails();

      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));

      //XML to Object Conversion
      Student student1 = (Student)xstream.fromXML(xml);
      System.out.println(student1);
   }

   private Student getStudentDetails() {

      Student student = new Student();
      student.setFirstName("Mahesh");
      student.setLastName("Parashar");
      student.setRollNo(1);
      student.setClassName("1st");

      Address address = new Address();
      address.setArea("H.No. 16/3, Preet Vihar.");
      address.setCity("Delhi");
      address.setState("Delhi");
      address.setCountry("India");
      address.setPincode(110012);

      student.setAddress(address);
      return student;
   }

   public static String formatXml(String xml) {

      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();

         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());

         serializer.transform(xmlSource, res);

         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());

      } catch(Exception e) {
         return xml;
      }
   }
}

class Student {
   private int rollNo;
   private String firstName;
   private String lastName;
   private String className;
   private Address address;

   public String getFirstName() {
      return firstName;
   }

   public void setFirstName(String firstName) {
      this.firstName = firstName;
   }

   public String getLastName() {
      return lastName;
   }

   public void setLastName(String lastName) {
      this.lastName = lastName;
   }

   public int getRollNo() {
      return rollNo;
   }

   public void setRollNo(int rollNo) {
      this.rollNo = rollNo;
   }

   public String getClassName() {
      return className;
   }

   public void setClassName(String className) {
      this.className = className;
   }

   public Address getAddress() {
      return address;
   }

   public void setAddress(Address address) {
      this.address = address;
   }

   public String toString() {
      StringBuilder stringBuilder = new StringBuilder();

      stringBuilder.append("Student [ ");
      stringBuilder.append("\nfirstName: ");
      stringBuilder.append(firstName);
      stringBuilder.append("\nlastName: ");
      stringBuilder.append(lastName);
      stringBuilder.append("\nrollNo: ");
      stringBuilder.append(rollNo);
      stringBuilder.append("\nclassName: ");
      stringBuilder.append(className);
      stringBuilder.append("\naddress: ");
      stringBuilder.append(address);
      stringBuilder.append(" ]");

      return stringBuilder.toString();
   }
}

class Address {
   private String area;
   private String city;
   private String state;
   private String country;
   private int pincode;

   public String getArea() {
      return area;
   }

   public void setArea(String area) {
      this.area = area;
   }

   public String getCity() {
      return city;
   }

   public void setCity(String city) {
      this.city = city;
   }

   public String getState() {
      return state;
   }

   public void setState(String state) {
      this.state = state;
   }

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }

   public int getPincode() {
      return pincode;
   }

   public void setPincode(int pincode) {
      this.pincode = pincode;
   }

   public String toString() {

      StringBuilder stringBuilder = new StringBuilder();

      stringBuilder.append("\nAddress [ ");
      stringBuilder.append("\narea: ");
      stringBuilder.append(area);
      stringBuilder.append("\ncity: ");
      stringBuilder.append(city);
      stringBuilder.append("\nstate: ");
      stringBuilder.append(state);
      stringBuilder.append("\ncountry: ");
      stringBuilder.append(country);
      stringBuilder.append("\npincode: ");
      stringBuilder.append(pincode);
      stringBuilder.append(" ]");

      return stringBuilder.toString();
   }
}

Verify the Result

使用以下 javac 编译器编译类:

C:\XStream_WORKSPACE>javac XStreamTester.java

现在,运行 XStreamTester 以查看结果 −

C:\XStream_WORKSPACE>java XStreamTester

Verify the output as follows

<?xml version = "1.0" encoding = "UTF-8"?>
<Student>
   <firstName>Mahesh</firstName>
   <lastName>Parashar</lastName>
   <rollNo>1</rollNo>
   <className>1st</className>
   <address>
      <area>H.No. 16/3, Preet Vihar.</area>
      <city>Delhi</city>
      <state>Delhi</state>
      <country>India</country>
      <pincode>110012</pincode>
   </address>
</Student>

Student [
   firstName: Mahesh
   lastName: Parashar
   rollNo: 1
   className: 1st
   address:
   Address [
      area: H.No. 16/3, Preet Vihar.
      city: Delhi
      state: Delhi
      country: India
      pincode: 110012
   ]
]

Steps to Remember

以下是需要考虑的重要步骤。

Step 1 − Create an XStream Object

通过传递 StaxDriver 创建一个 XStream 对象。StaxDriver 使用 Stax pull 解析器(在 Java 6 中可用),是一种快速的 xml 解析器。

XStream xstream = new XStream(new StaxDriver());

Step 2 − Serialize the Object to XML

使用 toXML() 方法来获取对象的 XML 字符串表示形式。

//Object to XML Conversion
String xml = xstream.toXML(student);

Step 3 − De-serialize XML to Get the Object

使用 fromXML() 方法从 XML 中获取对象。

//XML to Object Conversion
Student student1 = (Student)xstream.fromXML(xml);

XStream - Aliasing

别名化是在 XStream 中定制生成的 XML 或使用特定格式化 XML 的一种技术。我们假设是要使用以下 XML 格式来序列化/反序列化 Student 对象。

<student name = "Suresh">
   <note>
      <title>first</title>
      <description>My first assignment.</description>
   </note>

   <note>
      <title>second</title>
      <description>My second assignment.</description>
   </note>
</student>

基于上面的 XML 格式,我们来创建模型类。

class Student {
   private String studentName;
   private List<Note> notes = new ArrayList<Note>();

   public Student(String name) {
      this.studentName = name;
   }

   public void addNote(Note note) {
      notes.add(note);
   }

   public String getName() {
      return studentName;
   }

   public List<Note> getNotes() {
      return notes;
   }
}

class Note {
   private String title;
   private String description;

   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }

   public String getTitle() {
      return title;
   }

   public String getDescription() {
      return description;
   }
}

让我们使用 XStream 测试上述对象的序列化。

在 C:\>XStream_WORKSPACE\com\tutorialspoint\xstream 中创建一个名为 XStreamTester 的 java 类文件。

File: XStreamTester.java

package com.tutorialspoint.xstream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import java.util.ArrayList;
import java.util.List;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamTester {
   public static void main(String args[]) {

      XStreamTester tester = new XStreamTester();
      XStream xstream = new XStream(new StaxDriver());
      Student student = tester.getStudentDetails();

      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));
   }

   private Student getStudentDetails() {

      Student student = new Student("Mahesh");

      student.addNote(new Note("first","My first assignment."));
      student.addNote(new Note("second","My Second assignment."));

      return student;
   }

   public static String formatXml(String xml) {

      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();

         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());

         serializer.transform(xmlSource, res);

         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());

      } catch(Exception e) {
         return xml;
      }
   }
}

class Student {
   private String studentName;
   private List<Note> notes = new ArrayList<Note>();

   public Student(String name) {
      this.studentName = name;
   }

   public void addNote(Note note) {
      notes.add(note);
   }

   public String getName() {
      return studentName;
   }

   public List<Note> getNotes() {
      return notes;
   }
}

class Note {
   private String title;
   private String description;

   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }

   public String getTitle() {
      return title;
   }

   public String getDescription() {
      return description;
   }
}

Verify the Result

使用以下 javac 编译器编译类:

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>javac XStreamTester.java

现在,运行 XStreamTester 以查看结果 −

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>java XStreamTester

验证输出如下所示 −

<?xml version = "1.0" encoding = "UTF-8"?>
<com.tutorialspoint.xstream.Student>
   <studentName>Mahesh</studentName>
   <notes>
      <com.tutorialspoint.xstream.Note>
         <title>first</title>
         <description>My first assignment.</description>
      </com.tutorialspoint.xstream.Note>

      <com.tutorialspoint.xstream.Note>
         <title>second</title>
         <description>My Second assignment.</description>
     </com.tutorialspoint.xstream.Note>
   </notes>
</com.tutorialspoint.xstream.Student>

在上述结果中,Student 对象名称是完全限定的。要将其替换为 student 标签,请按照下一部分操作。

XStream - Annotations

XStream 支持注释,类似于自动配置,而不是编码。在上节中,我们在代码中看到了以下配置。

xstream.alias("student", Student.class);
xstream.alias("note", Note.class);

xstream.useAttributeFor(Student.class, "studentName");
xstream.aliasField("name", Student.class, "studentName");
xstream.addImplicitCollection(Student.class, "notes");

下面的代码片段说明了使用注释以更简单的方式完成相同工作的用法。

@XStreamAlias("student")   //define class level alias
class Student {

   @XStreamAlias("name")   //define field level alias
   @XStreamAsAttribute     //define field as attribute
   private String studentName;

   @XStreamImplicit        //define list as an implicit collection
   private List<Note> notes = new ArrayList<Note>();

   @XStreamOmitField       //omit a field to not to be a part of XML
   private int type;
}

让我们使用 XStream 测试上述注释。

在 C:\>XStream_WORKSPACE\com\tutorialspoint\xstream 中创建一个名为 XStreamTester 的 java 类文件。

File: XStreamTester.java

package com.tutorialspoint.xstream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import java.util.ArrayList;
import java.util.List;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamTester {

   public static void main(String args[]) {

      XStreamTester tester = new XStreamTester();
      XStream xstream = new XStream(new StaxDriver());
      Student student = tester.getStudentDetails();

      xstream.processAnnotations(Student.class);

      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));
   }

   private Student getStudentDetails() {

      Student student = new Student("Mahesh");

      student.addNote(new Note("first","My first assignment."));
      student.addNote(new Note("second","My Second assignment."));
      student.setType(1);

      return student;
   }

   public static String formatXml(String xml) {

      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();

         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res = new StreamResult(new ByteArrayOutputStream());

         serializer.transform(xmlSource, res);

         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());

      } catch(Exception e) {
         return xml;
      }
   }
}

@XStreamAlias("student")
class Student {

   @XStreamAlias("name")
   @XStreamAsAttribute
   private String studentName;

   @XStreamImplicit
   private List<Note> notes = new ArrayList<Note>();

   public Student(String name) {
      this.studentName = name;
   }

   public void addNote(Note note) {
      notes.add(note);
   }

   public String getName() {
      return studentName;
   }

   public List<Note> getNotes() {
      return notes;
   }

   @XStreamOmitField
   private int type;

   public int getType() {
      return type;
   }

   public void setType(int type) {
      this.type = type;
   }
}

@XStreamAlias("note")
class Note {
   private String title;
   private String description;

   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }

   public String getTitle() {
      return title;
   }

   public String getDescription() {
      return description;
   }
}

Verify the Result

使用以下 javac 编译器编译类:

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>javac XStreamTester.java

现在,运行 XStreamTester 以查看结果 −

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>java XStreamTester

验证输出如下所示 −

<?xml version = "1.0" encoding = "UTF-8"?>
<student name = "Mahesh">
   <note>
      <title>first</title>
      <description>My first assignment.</description>
   </note>

   <note>
      <title>second</title>
      <description>My Second assignment.</description>
   </note>
</student>

为了指示 XStream 框架处理注释,您需要在序列化 XML 之前添加以下命令。

xstream.processAnnotations(Student.class);

xstream.autodetectAnnotations(true);

XStream - Converters

XStream 转换器是 XStream 库的关键组件,它们负责将对象转换为 XML,反之亦然。XStream 为常用类型(如基本类型、String、File、Collections、数组和 Dates)提供了许多转换器。

Using Converter

让我们使用一个 SingleValueConvertor,其目的是将对象转换为单个字符串。我们将使用 SingleValueConvertor 将对象写入为属性字符串。

Create a Converter

class NameConverter implements SingleValueConverter {

   public Object fromString(String name) {
      String[] nameparts = name.split(",");
      return new Name(nameparts[0], nameparts[1]);
   }

   public String toString(Object name) {
      return ((Name)name).getFirstName() + "," + ((Name)name).getLastName();
   }

   public boolean canConvert(Class type) {
      return type.equals(Name.class);
   }
}

Register a Converter

xstream.registerConverter(new NameConverter());

Example without Converter

让我们首先在 XStream 中测试没有转换器的代码。

在 C:\>XStream_WORKSPACE\com\tutorialspoint\xstream 中创建一个名为 XStreamTester 的 java 类文件。

File: XStreamTester.java

package com.tutorialspoint.xstream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamTester {
   public static void main(String args[]) {

      XStreamTester tester = new XStreamTester();
      XStream xstream = new XStream(new StaxDriver());
      Student student = tester.getStudentDetails();
      xstream.autodetectAnnotations(true);

      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));
   }

   private Student getStudentDetails() {
      Student student = new Student("Mahesh","Parashar");
      return student;
   }

   public static String formatXml(String xml) {

      try {

         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();

         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());

         serializer.transform(xmlSource, res);

         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());

      } catch(Exception e) {
         return xml;
      }
   }
}

@XStreamAlias("student")
class Student {

   @XStreamAlias("name")
   @XStreamAsAttribute
   private Name studentName;

   public Student(String firstName, String lastName) {
      this.studentName = new Name(firstName, lastName);
   }

   public Name getName() {
      return studentName;
   }
}

class Name {
   private String firstName;
   private String lastName;

   public Name(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }
}

Verify the Result

使用以下 javac 编译器编译类:

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>javac XStreamTester.java

现在,运行 XStreamTester 以查看结果 −

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>java XStreamTester

验证输出如下所示 −

<?xml version = "1.0" encoding = "UTF-8"?>
<student>
   <name>
      <firstName>Mahesh</firstName>
      <lastName>Parashar</lastName>
   </name>
</student>

Example with Converter

现在让我们用 XStream 中的转换器测试代码。

在 C:\>XStream_WORKSPACE\com\tutorialspoint\xstream 中创建一个名为 XStreamTester 的 java 类文件。

File: XStreamTester.java

package com.tutorialspoint.xstream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamTester {

   public static void main(String args[]) {

      XStreamTester tester = new XStreamTester();
      XStream xstream = new XStream(new StaxDriver());
      Student student = tester.getStudentDetails();

      xstream.autodetectAnnotations(true);
      xstream.registerConverter(new NameConverter());

      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));
   }

   private Student getStudentDetails() {
      Student student = new Student("Mahesh","Parashar");
      return student;
   }

   public static String formatXml(String xml) {

      try {

         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();

         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res = new StreamResult(new ByteArrayOutputStream());

         serializer.transform(xmlSource, res);

         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());

      } catch(Exception e) {
         return xml;
      }
   }
}

@XStreamAlias("student")
class Student {

   @XStreamAlias("name")
   @XStreamAsAttribute
   private Name studentName;

   public Student(String firstName, String lastName) {
      this.studentName = new Name(firstName, lastName);
   }

   public Name getName() {
      return studentName;
   }
}

class Name {
   private String firstName;
   private String lastName;

   public Name(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }
}

class NameConverter implements SingleValueConverter  {

   public Object fromString(String name) {
      String[] nameparts = name.split(",");
      return new Name(nameparts[0], nameparts[1]);
   }

   public String toString(Object name) {
      return ((Name)name).getFirstName() + "," + ((Name)name).getLastName();
   }

   public boolean canConvert(Class type) {
      return type.equals(Name.class);
   }
}

Verify the Result

使用以下 javac 编译器编译类:

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>javac XStreamTester.java

现在,运行 XStreamTester 以查看结果 −

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>java XStreamTester

验证输出如下所示 −

<?xml version = "1.0" encoding = "UTF-8"?>
<student name = "Mahesh,Parashar"/>

XStream - Object Streams

XStream 提供了 java.io.ObjectInputStream 和 java.io.ObjectOutputStream 的替代实现,以便可以从 XML 序列化或反序列化对象流。当要处理大量对象集时,一次只保留一个对象在内存中时,这特别有用。

Syntax: createObjectOutputStream()

ObjectOutputStream objectOutputStream = xstream.createObjectOutputStream(
   new FileOutputStream("test.txt"));

Syntax: createObjectInputStream()

ObjectInputStream objectInputStream = xstream.createObjectInputStream(
   new FileInputStream("test.txt"));

现在让我们用 XStream 中的对象流测试代码。

在 C:\>XStream_WORKSPACE\com\tutorialspoint\xstream 中创建一个名为 XStreamTester 的 java 类文件。

File: XStreamTester.java

package com.tutorialspoint.xstream;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamTester {
   public static void main(String args[]) {

      XStreamTester tester = new XStreamTester();
      XStream xstream = new XStream(new StaxDriver());

      xstream.autodetectAnnotations(true);

      Student student1 = new Student("Mahesh","Parashar");
      Student student2 = new Student("Suresh","Kalra");
      Student student3 = new Student("Ramesh","Kumar");
      Student student4 = new Student("Naresh","Sharma");

      try {

         ObjectOutputStream objectOutputStream = xstream.createObjectOutputStream(
            new FileOutputStream("test.txt"));

         objectOutputStream.writeObject(student1);
         objectOutputStream.writeObject(student2);
         objectOutputStream.writeObject(student3);
         objectOutputStream.writeObject(student4);
         objectOutputStream.writeObject("Hello World");

         objectOutputStream.close();

         ObjectInputStream objectInputStream = xstream.createObjectInputStream(
            new FileInputStream("test.txt"));

         Student student5 = (Student)objectInputStream.readObject();
         Student student6 = (Student)objectInputStream.readObject();
         Student student7 = (Student)objectInputStream.readObject();
         Student student8 = (Student)objectInputStream.readObject();

         String text = (String)objectInputStream.readObject();

         System.out.println(student5);
         System.out.println(student6);
         System.out.println(student7);
         System.out.println(student8);
         System.out.println(text);

      } catch (IOException e) {
         e.printStackTrace();

      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
}

@XStreamAlias("student")
class Student {

   private String firstName;
   private String lastName;

   public Student(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }

   public String toString() {
      return "Student [ firstName: "+firstName+", lastName: "+ lastName+ " ]";
   }
}

Verify the Result

使用以下 javac 编译器编译类:

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>javac XStreamTester.java

现在,运行 XStreamTester 以查看结果 −

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>java XStreamTester

验证输出如下所示 −

Student [ firstName: Mahesh, lastName: Parashar ]
Student [ firstName: Suresh, lastName: Kalra ]
Student [ firstName: Ramesh, lastName: Kumar ]
Student [ firstName: Naresh, lastName: Sharma ]
Hello World

查看 C:\>XStream_WORKSPACE\com\tutorialspoint\xstream 文件夹中的 test.txt 的内容。

<?xml version = "1.0" ?>
<object-stream>
   <student>
      <firstName>Mahesh</firstName>
      <lastName>Parashar</lastName>
   </student>

   <student>
      <firstName>Suresh</firstName>
      <lastName>Kalra</lastName>
   </student>

   <student>
      <firstName>Ramesh</firstName>
      <lastName>Kumar</lastName>
   </student>

   <student>
      <firstName>Naresh</firstName>
      <lastName>Sharma</lastName>
   </student>
   <string>Hello World</string>
</object-stream>

XStream - Writing JSON using XStream

XStream 通过使用适当的驱动程序初始化 XStream 对象来支持 JSON。XStream 目前支持 JettisonMappedXmlDriver 和 JsonHierarchicalStreamDriver。

现在让我们用 XStream 中的 json 处理测试代码。

在 C:\>XStream_WORKSPACE\com\tutorialspoint\xstream 中创建一个名为 XStreamTester 的 java 类文件。

File: XStreamTester.java

package com.tutorialspoint.xstream;

import java.io.Writer;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import com.thoughtworks.xstream.io.json.JsonWriter;

public class XStreamTester {

   public static void main(String args[]) {

      XStreamTester tester = new XStreamTester();
      XStream xstream = new XStream(new JsonHierarchicalStreamDriver() {

         public HierarchicalStreamWriter createWriter(Writer writer) {
            return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
         }
      });

      Student student = new Student("Mahesh","Parashar");

      xstream.setMode(XStream.NO_REFERENCES);
      xstream.alias("student", Student.class);

      System.out.println(xstream.toXML(student));
   }
}

@XStreamAlias("student")
class Student {

   private String firstName;
   private String lastName;

   public Student(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }

   public String toString() {
      return "Student [ firstName: "+firstName+", lastName: "+ lastName+ " ]";
   }
}

Verify the Result

使用以下 javac 编译器编译类:

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>javac XStreamTester.java

现在,运行 XStreamTester 以查看结果 −

C:\XStream_WORKSPACE\com\tutorialspoint\xstream>java XStreamTester

验证输出如下所示 −

{
   "firstName": "Mahesh",
   "lastName": "Parashar"
}