Hướng dẫn sử dụng Java XStream
Công ty Vĩnh Cửu tuyển dụng lập trình viên Java

1- XStream là gì?

XStream là một thư viện mã nguồn mở Java, nó được sử dụng để chuyển đổi một đối tượng Java thành một tài liệu XML và ngược lại.

2- Thư viện XStream

Bạn có thể download thư viện XStream tại:
Hoặc khai báo sử dụng thư viện XStream với Maven:
<!-- http://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.4.8</version>
</dependency>

3- Tạo nhanh một Project để làm việc với XStream

Ở đây tôi tạo nhanh một Maven project.
  • File/New/Other..
Nhập vào:
  • Group Id: org.o7planning
  • Artifact Id: XStreamTutorial
  • Package: org.o7planning.xstreamtutorial
Khai báo thư viện XStream với Maven.
  • pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.o7planning</groupId>
    <artifactId>XStreamTutorial</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>XStreamTutorial</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
    
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- http://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.8</version>
        </dependency>
        
    </dependencies>
    
</project>

4- Một vài class tham gia trong các ví dụ

  • Address.java
package org.o7planning.xstreamtutorial.beans;

public class Address {
    
    private String street;
    private String city;

    public Address() {

    }

    public Address(String street, String city) {
        this.street = street;
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

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

    @Override
    public String toString() {
        return street + ", " + city;
    }
    
}
  • Company.java
package org.o7planning.xstreamtutorial.beans;

public class Company {

    private int id;
    private String name;
    private String[] websites;
    private Address address;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String[] getWebsites() {
        return websites;
    }

    public void setWebsites(String[] websites) {
        this.websites = websites;
    }

    public Address getAddress() {
        return address;
    }

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

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();

        sb.append("\n id:" + this.id);
        sb.append("\n name:" + this.name);
        if (this.websites != null) {
            sb.append("\n website: ");
            for (String website : this.websites) {
                sb.append(website + ", ");
            }
        }
        if (this.address != null) {
            sb.append("\n address:" + this.address.toString());
        }
        return sb.toString();
    }

}
  • DataDAO.java
package org.o7planning.xstreamtutorial;

import org.o7planning.xstreamtutorial.beans.Address;
import org.o7planning.xstreamtutorial.beans.Company;

public class DataDAO {

    
    
    public static Company createCompany() {

        Company company = new Company();
        company.setId(111);
        company.setName("Microsoft");

        String[] websites = { "http://microsoft.com",
                "http://msn.com", "http://hotmail.com" };
        company.setWebsites(websites);

        Address address = new Address();
        address.setCity("Redmond");
        address.setStreet("1 Microsoft Way");

        company.setAddress(address);

        return company;
    }
    
}

5- Chuyển đối tượng Java thành XML

Khác với JAXB, XStream có thể chuyển một đối tượng Java thành XML mà không cần một ánh xạ (mapping), nó sử dụng một ánh xạ mặc định. Hãy xem ví dụ sau:
  • JavaObject2Xml.java
package org.o7planning.xstreamtutorial;

import org.o7planning.xstreamtutorial.beans.Company;

import com.thoughtworks.xstream.XStream;

public class JavaObject2Xml {

    public static void main(String[] args) {
        
        Company company = DataDAO.createCompany();
        
        XStream xs = new XStream();
        
        
        // JAVA OBJECT --> XML
        String xml = xs.toXML(company);
        
        System.out.println(xml);
    }
    
    
}
Chạy ví dụ:
<org.o7planning.xstreamtutorial.beans.Company>
  <id>111</id>
  <name>Microsoft</name>
  <websites>
    <string>http://microsoft.com</string>
    <string>http://msn.com</string>
    <string>http://hotmail.com</string>
  </websites>
  <address>
    <street>1 Microsoft Way</street>
    <city>Redmond</city>
  </address>
</org.o7planning.xstreamtutorial.beans.Company>

6- Sử dụng Alias (Bí danh)

Trong khi chuyển đổi đối tượng Java thành XML, XStream chuyển đổi class thành một tên thẻ XML mặc định. Bí danh hóa (Aliasing) chính là kỹ thuật để tùy chỉnh XML được tạo ra. Có 5 kiểu bí danh:
  1. Bí danh class
  2. Bí danh trường (field)
  3. Ngầm định bí danh cho kiểu tập hợp
  4. Bí danh thuộc tính
  5. Bí danh Package

6.1- Bí danh class

  • ClassAliasingExample.java
package org.o7planning.xstreamtutorial;

import org.o7planning.xstreamtutorial.beans.Company;

import com.thoughtworks.xstream.XStream;

public class ClassAliasingExample {

    public static void main(String[] args) {
        
        Company company = DataDAO.createCompany();
        
        XStream xs = new XStream();
        
        xs.alias("company", Company.class);
        
        // JAVA OBJECT --> XML
        String xml = xs.toXML(company);
        
        System.out.println(xml);
    }
    
}
Chạy ví dụ
<company>
 <id>111</id>
 <name>Microsoft</name>
 <websites>
   <string>http://microsoft.com</string>
   <string>http://msn.com</string>
   <string>http://hotmail.com</string>
 </websites>
 <address>
   <street>1 Microsoft Way</street>
   <city>Redmond</city>
 </address>
</company

6.2- Bí danh trường (field)

  • FieldAliasingExample.java
package org.o7planning.xstreamtutorial;

import org.o7planning.xstreamtutorial.beans.Company;

import com.thoughtworks.xstream.XStream;

public class FieldAliasingExample {

    public static void main(String[] args) {
        
        Company company = DataDAO.createCompany();
        
        XStream xstream = new XStream();
        
        // Class aliasing.
        xstream.alias("company", Company.class);
        
        // Field aliasing.
        // aliasField(String alias, Class definedIn, String fieldName).
        xstream.aliasField("companyName", Company.class, "name");
        xstream.aliasField("companyId", Company.class, "id");
        
        // JAVA OBJECT --> XML
        String xml = xstream.toXML(company);
        
        System.out.println(xml);
    }
    
}
Chạy ví dụ:
<company>
  <companyId>111</companyId>
  <companyName>Microsoft</companyName>
  <websites>
    <string>http://microsoft.com</string>
    <string>http://msn.com</string>
    <string>http://hotmail.com</string>
  </websites>
  <address>
    <street>1 Microsoft Way</street>
    <city>Redmond</city>
  </address>
</company>

6.3- Bí danh ngầm định tập hợp

Thông thường một tập hợp (Mảng và Collections) trong Java khi được chuyển sang XML nó được bao trong một thẻ. Bạn có thể sử dụng bí danh ngầm định cho tập hợp để loại bỏ thẻ này.
  • ImplicitCollectionsAliasingExample.java
package org.o7planning.xstreamtutorial;

import org.o7planning.xstreamtutorial.beans.Company;

import com.thoughtworks.xstream.XStream;

public class ImplicitCollectionsAliasingExample {

    public static void main(String[] args) {
        
        Company company = DataDAO.createCompany();
        
        XStream xstream = new XStream();
        
        // Class aliasing.
        xstream.alias("company", Company.class);
        
        
        // addImplicitArray(Class ownerType, String fieldName).
        xstream.addImplicitArray(Company.class, "websites", "website");
        
        // JAVA OBJECT --> XML
        String xml = xstream.toXML(company);
        
        System.out.println(xml);

    }

}
Chạy ví dụ:
<company>
  <id>111</id>
  <name>Microsoft</name>
  <website>http://microsoft.com</website>
  <website>http://msn.com</website>
  <website>http://hotmail.com</website>
  <address>
    <street>1 Microsoft Way</street>
    <city>Redmond</city>
  </address>
</company>

6.4- Bí danh thuộc tính

  • AttributeAliasingExample.java
package org.o7planning.xstreamtutorial;

import org.o7planning.xstreamtutorial.beans.Company;

import com.thoughtworks.xstream.XStream;

public class AttributeAliasingExample {

    public static void main(String[] args) {
        
        Company company = DataDAO.createCompany();
        
        XStream xstream = new XStream();
        
        // Class aliasing.
        xstream.alias("company", Company.class);
        
        
        // useAttributeFor(Class definedIn, String fieldName).
        xstream.useAttributeFor(Company.class, "id");         
        
        xstream.useAttributeFor(Company.class, "name");
        xstream.aliasAttribute("companyName", "name");
        
        // JAVA OBJECT --> XML
        String xml = xstream.toXML(company);
        
        System.out.println(xml);

    }

}
Chạy ví dụ:
<company id="111" companyName="Microsoft">
  <websites>
    <string>http://microsoft.com</string>
    <string>http://msn.com</string>
    <string>http://hotmail.com</string>
  </websites>
  <address>
    <street>1 Microsoft Way</street>
    <city>Redmond</city>
  </address>
</company>

6.5- Bí danh Package

  • PackageAliasingExample.java
package org.o7planning.xstreamtutorial;

import org.o7planning.xstreamtutorial.beans.Address;
import org.o7planning.xstreamtutorial.beans.Company;

import com.thoughtworks.xstream.XStream;

public class PackageAliasingExample {

    public static void main(String[] args) {
        
        Company company = DataDAO.createCompany();
        
        XStream xstream = new XStream();  
        
        String packgeName=  Address.class.getPackage().getName();
        
        // aliasPackage(String name, String pkgName).
        xstream.aliasPackage("com.newcompany", packgeName);          
        
        
        
        // JAVA OBJECT --> XML
        String xml = xstream.toXML(company);
        
        System.out.println(xml);

    }

}
Chạy ví dụ:
<com.newcompany.Company>
  <id>111</id>
  <name>Microsoft</name>
  <websites>
    <string>http://microsoft.com</string>
    <string>http://msn.com</string>
    <string>http://hotmail.com</string>
  </websites>
  <address>
    <street>1 Microsoft Way</street>
    <city>Redmond</city>
  </address>
</com.newcompany.Company>

7- XStream Annotation

Với XStream bạn có thể sử dụng code để tùy chỉnh XML tạo ra từ đối tượng Java, theo cách sử dụng Alias đã được đề cập ở trên. Tuy nhiên bạn cũng có thể sử dụng Annotation để nói với XStream cách tạo ra XML từ đối tượng Java.

Dưới đây là danh sách các Annotation:
  • @XStreamAlias
  • @XStreamAsAttribute
  • @XStreamImplicit
  • @XStreamOmitField
Sử dụng code Sử dụng Annotation
xs.alias("dept", Department.class); @XStreamAlias("dept")
public class Department {

}
xs.aliasField("no", Department.class, "deptNo"); @XStreamAlias("no")
private int deptNo;
xs.useAttributeFor(Department.class, "deptNo") @XStreamAsAttribute
private int deptNo;
xs.omitField(Employee.class, "bonus"); @XStreamOmitField
private float bonus;
xs.addImplicitCollection(Department.class, "employees"); @XStreamImplicit
private List<Employee> employees;
  • Department.java
package org.o7planning.xstreamtutorial.beans;

import java.util.List;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

@XStreamAlias("dept")
public class Department {

   @XStreamAlias("no")
   @XStreamAsAttribute
   private int deptNo;

   @XStreamAlias("name")
   private String deptName;

   @XStreamImplicit
   private List<Employee> employees;

   public int getDeptNo() {
       return deptNo;
   }

   public void setDeptNo(int deptNo) {
       this.deptNo = deptNo;
   }

   public String getDeptName() {
       return deptName;
   }

   public void setDeptName(String deptName) {
       this.deptName = deptName;
   }

   public List<Employee> getEmployees() {
       return employees;
   }

   public void setEmployees(List<Employee> employees) {
       this.employees = employees;
   }

}
  • Employee.java
package org.o7planning.xstreamtutorial.beans;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamOmitField;

@XStreamAlias("emp")
public class Employee {

   @XStreamAlias("no")
   @XStreamAsAttribute
   private int empNo;
   private String empName;

   private float salary;
 
   // Trường này bị bỏ qua.
   @XStreamOmitField
   private float bonus;

   public Employee(int empNo, String empName, float salary) {
       this.empNo = empNo;
       this.empName = empName;
       this.salary = salary;
   }

   public int getEmpNo() {
       return empNo;
   }

   public void setEmpNo(int empNo) {
       this.empNo = empNo;
   }

   public String getEmpName() {
       return empName;
   }

   public void setEmpName(String empName) {
       this.empName = empName;
   }

   public float getSalary() {
       return salary;
   }

   public void setSalary(float salary) {
       this.salary = salary;
   }

   public float getBonus() {
       return bonus;
   }

   public void setBonus(float bonus) {
       this.bonus = bonus;
   }

}
  • XStreamAnnotationExample.java
package org.o7planning.xstreamtutorial;

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

import org.o7planning.xstreamtutorial.beans.Department;
import org.o7planning.xstreamtutorial.beans.Employee;

import com.thoughtworks.xstream.XStream;

public class XStreamAnnotationExample {

   public static void main(String[] args) {
       Department dept = createDepartment();

       XStream xstream = new XStream();
       
       // Sử dụng các chú thích trên class Department
       xstream.processAnnotations(Department.class);
       
       // Sử dụng các chú thích trên class Employee
       xstream.processAnnotations(Employee.class);
       
       String xml = xstream.toXML(dept);
       
       System.out.println(xml);
   }

   public static Department createDepartment() {
       Department dept = new Department();
       dept.setDeptNo(10);
       dept.setDeptName("ACCOUNTING");

       Employee king = new Employee(7839, "KING", 5000f);
       Employee clark = new Employee(7839, "CLARK", 2450f);
       Employee miller = new Employee(7839, "MILLER", 1300f);

       List<Employee> list = new ArrayList<Employee>();
       list.add(king);
       list.add(clark);
       list.add(miller);
       dept.setEmployees(list);
       return dept;
   }
   
}
Chạy ví dụ:
<dept no="10">
  <name>ACCOUNTING</name>
  <emp no="7839">
    <empName>KING</empName>
    <salary>5000.0</salary>
  </emp>
  <emp no="7839">
    <empName>CLARK</empName>
    <salary>2450.0</salary>
  </emp>
  <emp no="7839">
    <empName>MILLER</empName>
    <salary>1300.0</salary>
  </emp>
</dept>

8- XStream Converter

XStream Converter là một thành phần quan trọng nhất trong thư viện XStream, nó là API dùng để chuyển đổi một đối tượng Java thành một XML và ngược lại. Bạn có thể tự tạo một converter dùng để tùy biến chuyển đổi giữa Java và XML:
  • TODO