Java: Serializzare un oggetto in XML
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).