目录

XStream - 快速指南

XStream - Overview

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

特点 (Features)

  • Easy to use - XStream API提供了一个高级外观,以简化常见用例。

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

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

  • Clean XML - XStream可生成简洁易读的简洁XML输出。

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

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

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

  • Security framework - XStream提供对未编组类型的公平控制,以防止受操纵输入的安全问题。

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

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

常见用途

  • Transport - XML是对象的文本表示,可用于通过线路传输对象,而不依赖于所使用的序列化/反序列化技术。

  • Persistence - 对象可以在数据库中作为XML持久化,并且可以在需要时进行编组/解组。

  • Configuration - XML不言自明,大量用于定义配置。 在将对象转换为XML表示后,对象也可用于配置目的。

  • Unit Tests - XStream API兼容JUnit,可用于增强应用程序模块的单元测试。

XStream - Environment Setup

在本章中,我们将讨论为Java建立适宜环境的不同方面。

本地环境设置 (Local Environment Setup)

如果要为Java编程语言设置环境,本节将介绍如何在计算机上下载和设置Java。 请按照下面给出的步骤设置Java环境。

Java SE可以从链接免费下载 -

下载Java

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

设置Windows 2000/XP的路径

假设您已在c:\Program Files\java\jdk目录中安装了Java -

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

  • 单击“高级”选项卡下的“环境变量”按钮。

  • 更改“Path”变量,以便它还包含Java可执行文件的路径。 例如,如果路径当前设置为“C:\WINDOWS\SYSTEM32”,则将路径更改为“C:\WINDOWS\SYSTEM32; c:\Program Files\java\jdk\bin”。

设置Windows 95/98/ME的路径

假设您已在c:\Program Files\java\jdk目录中安装了Java -

  • 编辑'C:\autoexec.bat'文件并在结尾添加以下行 -

    'SET PATH =%PATH%; C:\Program Files\java\jdk\bin'

设置Linux,UNIX,Solaris,FreeBSD的路径

应将环境变量PATH设置为指向已安装Java二进制文件的位置。 如果您在执行此操作时遇到问题,请参阅您的shell文档。

例如,如果您使用bash作为shell,那么您将在'.bashrc的末尾添加以下行:export PATH =/path/to/java:$ PATH'

流行的Java编辑器 (Popular Java Editors)

要编写Java程序,您需要一个文本编辑器。 市场上还有更复杂的IDE。 但就目前而言,您可以考虑以下其中一项 -

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

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

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

下载XStream存档

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

OS 存档名称
Windowsxstream-1.4.7.jar
Linuxxstream-1.4.7.jar
Macxstream-1.4.7.jar

设置XStream环境

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

Sr.No. 操作系统和描述
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.7.jar存储在XStream文件夹中。

Sr.No. 操作系统和描述
1

Windows

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

2

Linux

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

3

Mac

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

XStream - First Application

在进入XStream库的详细信息之前,让我们看一下应用程序的运行情况。 在这个例子中,我们创建了Student和Address类。 我们将创建一个student对象,然后将其序列化为XML String。 然后反序列化相同的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
   ] 
]

要记住的步骤

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

第1步:创建一个XStream对象

通过传递一个StaxDriver来创建一个XStream对象。 StaxDriver使用Stax pull解析器(可从java 6获得)并且是一个快速的xml解析器。

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

第2步:将对象序列化为XML

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

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

第3步:反序列化XML以获取对象

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

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

XStream - Aliasing

别名是一种自定义生成的XML或使用XStream使用特定格式的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\iowiki\xstream中创建名为XStreamTester的java类文件。

File: XStreamTester.java

package com.iowiki.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\iowiki\xstream>javac XStreamTester.java

现在运行XStreamTester来查看结果 -

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

验证输出如下 -

<?xml version = "1.0" encoding = "UTF-8"?>
<com.iowiki.xstream.Student>
   <studentName>Mahesh</studentName>
   <notes>
      <com.iowiki.xstream.Note>
         <title>first</title>
         <description>My first assignment.</description>
      </com.iowiki.xstream.Note>
      <com.iowiki.xstream.Note>
         <title>second</title>
         <description>My Second assignment.</description>
     </com.iowiki.xstream.Note>
   </notes>
</com.iowiki.xstream.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\iowiki\xstream中创建名为XStreamTester的java类文件。

File: XStreamTester.java

package com.iowiki.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;
   }     
}

验证结果

使用javac编译器编译类如下 -

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

现在运行XStreamTester来查看结果 -

C:\XStream_WORKSPACE\com\iowiki\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);		

OR

xstream.autodetectAnnotations(true);

XStream - Converters

XStream转换器是XStream库的关键组件,它负责将对象转换为XML,反之亦然。 XStream为常见类型提供了大量转换器,例如基元,字符串,文件,集合,数组和日期。

使用转换器

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

创建转换器

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);
   }	
}

注册转换器

xstream.registerConverter(new NameConverter());

示例没有转换器

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

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

File: XStreamTester.java

package com.iowiki.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\iowiki\xstream>javac XStreamTester.java

现在运行XStreamTester来查看结果 -

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

验证输出如下 -

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

转换器示例

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

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

File: XStreamTester.java

package com.iowiki.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\iowiki\xstream>javac XStreamTester.java

现在运行XStreamTester来查看结果 -

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

验证输出如下 -

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

Custom Converter

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\iowiki\xstream中创建名为XStreamTester的java类文件。

File: XStreamTester.java

package com.iowiki.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\iowiki\xstream>javac XStreamTester.java

现在运行XStreamTester来查看结果 -

C:\XStream_WORKSPACE\com\iowiki\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\iowiki\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\iowiki\xstream中创建名为XStreamTester的java类文件。

File: XStreamTester.java

package com.iowiki.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+ " ]";
   }	
}

验证结果

使用javac编译器编译类如下 -

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

现在运行XStreamTester来查看结果 -

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

验证输出如下 -

{
   "firstName": "Mahesh",
   "lastName": "Parashar"
}
↑回到顶部↑
WIKI教程 @2018