XStream - Convertisseur personnalisé

XStream permet d'écrire un convertisseur à partir de zéro, afin que le développeur puisse écrire une implémentation complètement nouvelle sur la façon de sérialiser un objet en XML et vice versa. Une interface de convertisseur propose trois méthodes -

  • canConvert - Il s'agit d'une vérification de la sérialisation du type d'objet pris en charge.

  • marshal - Il sérialise un objet en XML.

  • unmarshal - Il désérialise un objet de XML.

Étape 1: implémenter l'interface du convertisseur

class StudentConverter implements Converter {

   public boolean canConvert(Class object) {
      return object.equals(Student.class);
   }
   
   public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
      Student student = (Student) value;
      writer.startNode("name");
      writer.setValue(student.getName().getFirstName() + "," + student.getName().getLastName());
      writer.endNode();
   }
   
   public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
      reader.moveDown();
      String[] nameparts = reader.getValue().split(",");
      Student student = new Student(nameparts[0],nameparts[1]);
      reader.moveUp();
      return student;
   }
}

Étape 2: Enregistrer le convertisseur

xstream.registerConverter(new StudentConverter());

Testons maintenant le code avec le convertisseur dans XStream.

Créez un fichier de classe Java nommé XStreamTester dans C:\>XStream_WORKSPACE\com\tutorialspoint\xstream.

Fichier: 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.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 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 StudentConverter());
      
      //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")
   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 StudentConverter implements Converter {

   public void marshal(Object value, HierarchicalStreamWriter writer,
      MarshallingContext context) {
      Student student = (Student) value;
      writer.startNode("name");
      writer.setValue(student.getName().getFirstName() + "," + student.getName().getLastName());
      writer.endNode();
   }

   public Object unmarshal(HierarchicalStreamReader reader,
      UnmarshallingContext context) {
      reader.moveDown();
      String[] nameparts = reader.getValue().split(",");
      Student student = new Student(nameparts[0],nameparts[1]);
      reader.moveUp();
      return student;
   }

   public boolean canConvert(Class object) {
      return object.equals(Student.class);
   }
}

Vérifiez le résultat

Compilez les classes en utilisant javac compilateur comme suit -

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

Maintenant, lancez XStreamTester pour voir le résultat -

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

Vérifiez la sortie comme suit -

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