L’API di Java (dalla versione 1.4) mette a disposizione la classe XMLEncoder per serializzare un oggetto (un JavaBean) e ottenerne una rappresentazione testuale , sotto forma di documento XML.
Dualmente, è possibile deserializzare un oggetto utilizzando la classe XMLDecoder.

Il costruttore della classe XMLEncoder ha questa firma:

XMLEncoder(OutputStream out)

accetta come parametro, genericamente, un OutputStream.

Nel nostro esempio serializzeremo un oggetto Person che contiene qualche dato come il nome e il cognome, oltre ad un oggetto di tipo Address:

Address

public class Address {
  private String addr;
  private int number;

  public Address() {}

  public Address(String addr, int number) {
    this.addr = addr;
    this.number = number;
  }

  public void setAddr(String addr) {
    this.addr = addr;
  }

  public String getAddr() {
    return addr;
  }

  public void setNumber(int number) {
    this.number = number;
  }

  public int getNumber() {
    return number;
  }
}

Person

public class Person {
  private String firstName;
  private String lastName;
  private Address address;
  private String passport;
  private String info = "Some standard info";

  public Person() {}

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

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

  public Address getAddress() {
    return address;
  }

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

  public String getFirstName() {
    return firstName;
  }

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

  public String getLastName() {
    return lastName;
  }

  public void setPassport(String passport) {
    this.passport = passport;
  }

  public String getPassport() {
    return passport;
  }

  public void setInfo(String info) {
    this.info = info;
  }

  public String getInfo() {
    return info;
  }
}

XMLEncoderTest

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class XMLEncoderTest {
  public static void main(String[] args) throws Throwable{
    new XMLEncoderTest().runTest();
  }

  public void runTest() throws Throwable{
    Person p = new Person("Mario", "Rossi");
    p.setAddress(new Address("Corso Roma", 12));

    //XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("Person.xml"))); // se volessimo scrivere su file
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    XMLEncoder encoder = new XMLEncoder(out);
    encoder.writeObject(p);
    encoder.close();
    System.out.println(out.toString());

    XMLDecoder decoder = new XMLDecoder(new ByteArrayInputStream(out.toString().getBytes()));
    Person q = (Person)decoder.readObject();
    decoder.close();

    System.out.println(q.getFirstName() + " "
        + q.getLastName() + " "
        + q.getAddress().getAddr() + " "
        + q.getAddress().getNumber());
  }
}

Nel dettaglio, scriviamo l’oggetto serializzato in un ByteArrayOutputStream che servirà come base per un oggetto ByteArrayInputStream che useremo per deserializzare l’oggetto.
L’output del programma è il seguente:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_21" class="java.beans.XMLDecoder">
 <object class="Person">
  <void property="address">
   <object class="Address">
    <void property="addr">
     <string>Corso Roma</string>
    </void>
    <void property="number">
     <int>12</int>
    </void>
   </object>
  </void>
  <void property="firstName">
   <string>Mario</string>
  </void>
  <void property="lastName">
   <string>Rossi</string>
  </void>
 </object>
</java> 

Mario Rossi Corso Roma 12

Di interessante notiamo alcune cose.
La composizione tra Person e Address è chiaramente visibile nella gerarchia dei nodi XML.
Notiamo poi che due attributi della classe Person non sono presenti nel documento: passport e info. Questo perchè l’XMLEncoder applica un algoritmo per compattare l’XML, omettendo quelle proprietà che hanno valori di default (null per passport e lo string literal per info).