Dzisiaj omówimy bibliotekę służącą do serializacji obiektów w Javie – XStream.

Serializacja w Javie

Po co nam biblioteka do serializacji skoro sama Java dostarcza nam taki mechanizm? Spójrzmy zatem jak to wygląda w Javie.

Na początku stwórzmy sobie prostą klasę z kilkoma polami, której instancje będziemy serializować.

package pl.lantkowiak;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class SerializableClass implements Serializable {
	private int field1;
	private String field2;
	private List<Integer> field3;
	private InnerClass field4;

	public SerializableClass(int field1, String field2, List<Integer> field3, InnerClass field4) {
		this.field1 = field1;
		this.field2 = field2;
		this.field3 = field3;
		this.field4 = field4;
	}

	public static class InnerClass implements Serializable {
		private double innerField1;
		private String innerField2;

		public InnerClass(double innerField1, String innerField2) {
			this.innerField1 = innerField1;
			this.innerField2 = innerField2;
		}
	}
}

Teraz stwórzmy instancje naszej klasy i ją zserializujmy, a następnie zdeserializujmy.

final List<Integer> field3 = new ArrayList<>();
field3.add(45);
field3.add(78);
field3.add(12);
final InnerClass field4 = new InnerClass(3.0, "inner class");

final SerializableClass serializableClass = new SerializableClass(13, "sc", field3, field4);

 // serializacja
 try (FileOutputStream fout = new FileOutputStream("C:\\file.txt");
 ObjectOutputStream oos = new ObjectOutputStream(fout)) {
 oos.writeObject(serializableClass);
 }

 // deserializacja
 try (FileInputStream fin = new FileInputStream("C:\\file.txt");
 ObjectInputStream ois = new ObjectInputStream(fin)) {
 final SerializableClass deserialized = (SerializableClass) ois.readObject();
 }

Jak widzimy sama serializacja jest dosyć prosta i możemy ją łatwo wykonać w kilku liniach kodu.

Zerknijmy teraz do naszego pliku, który zawiera zserializowany obiekt.

...

Jak widzimy nie jest to zbyt czytelne 😉

Niestety z tego pliku nie jesteśmy w stanie w łatwy sposób odczytać zserializowanych wartości, nie mówiąc o ich edycji.

XStream w akcji!

I tutaj z pomocą przychodzi XStream!

Na początku musimy dodać zależność do naszego projektu:

<dependency>
	<groupId>xstream</groupId>
	<artifactId>xstream</artifactId>
	<version>1.2.2</version>
</dependency>

Zróbmy teraz najprostszą serializacje i deserializacje naszego obiektu.

// serializacja
XStream xstream = new XStream();
try (FileOutputStream fout = new FileOutputStream("C:\\file.xml")) {
 xstream.toXML(serializableClass, fout);
}

// deserializacja
try (FileInputStream fin = new FileInputStream("C:\\file.xml")) {
 final SerializableClass deserialized = (SerializableClass) xstream.fromXML(fin);
}

Jak widać operacje te przy użyciu XStream również możemy wykonać przy użyciu kilku linii kodu.

Na samym początku musimy stworzyć instancje XStream, a następnie wywołać na niej odpowiednio metody toXML lub fromXML. Pierwsza metoda przyjmuje jako parametry obiekt, który ma być zserializowany oraz OutputStream, do którego zserializowany obiekt ma być zapisany. Druga metoda natomiast na wejście przyjmuje InputStream, z którego ma być odczytany zserializowany obiekt, a na wyjściu otrzymujemy nasz zdeserializowany obiekt.

Zajrzyjmy teraz do pliku z zserializowanym obiektem.

<pl.lantkowiak.SerializableClass>
  <field1>13</field1>
  <field2>sc</field2>
  <field3>
    <int>45</int>
    <int>78</int>
    <int>12</int>
  </field3>
  <field4>
    <innerField1>3.0</innerField1>
    <innerField2>inner class</innerField2>
  </field4>
</pl.lantkowiak.SerializableClass>

Jak widać plik jest w formacie XML (co mogła sugerować nazwa metody toXML ;)). Z pliku możemy odczytać, która klasa jest zserializowana – pl.lantkowiak.SerializableClass. Widzimy też pełną strukturę klasy wraz z wartościami poszczególnych pól. Dzięki temu bez problemu możemy odczytać jak wygląda zapisany obiekt, a w razie potrzeby możemy go bez problemy edytować.

Podsumowanie

Dzisiaj zapoznaliśmy się z biblioteką XStream, której możemy użyć do serializacji obiektów do XMLa, dzięki czemu zserializowany obiekt będzie dla nas czytelny i łatwy do modyfikacji.

XStream posiada jeszcze bardziej zaawansowane opcje, z którymi warto się w przyszłości zapoznać 🙂