XML als Datenaustauschformat / Objektserialisierung mit Java

Objektserialisierung mit Java

Objektserialisierung mit Java

➪ Die XML-basierte Objektserialisierung zielt darauf ab, Objekte verschiedener Programmiersprachen (hier im Beispiel: Java) in XML abzubilden, um die generierte XML-Datei anschließend wieder auszulesen und in Java-Objekte zu überführen. Dabei gibt es verschiedene Verfahren, u.a. mit Hilfe von XMLEncoder und XMLDecoder.

Nehmen wir an, wir hätten ein Java-Interface "IXMLTest" zur Verfügung, das diverse Getter- und Setter-Methoden für noch zu implementierende Java-Klassen "Mensch" und "Person" vorgibt.


public interface IXMLTest {
  void setNN(String nn);
  String getNN();
  void setVN(String vn);
  String getVN();
  void setA(int a);
  int getA();
}

Dieses Interface ist Grundlage für die Klasse "Mensch". Zusätzlich zu den Vorgaben des Interfaces "IXMLTest" gibt es hier noch ein Datenfeld "hobby".


public class Mensch 
       implements IXMLTest, Serializable {
  private String vorname, nachname, hobby;
  private int alter;
  //Getters, Setters
  //implemented methods
  //Constructors
}

Arbeiten mit ObjectOutputStream und ObjectInputStream

Mit einem entsprechenden Konstruktor, der die vier Parameter übernimmt, ist es möglich, ein Objekt der Klasse "Mensch" zu generieren und dieses Objekt in eine Textdatei (noch nicht XML) zu schreiben, um es später wiederauslesen zu können. In einfachster Form geschieht das durch den ObjectOutputStream:


  IXMLTest m = new Mensch
           ("Wilma", "Wolkenlos", 33, "XML");
  FileOutputStream fos = null;
  ObjectOutputStream out = null;
  try {
      fos = new FileOutputStream("C:/wg/javaobject.ser");
      out = new ObjectOutputStream(fos);
      out.writeObject(m);
      out.close();
  } catch (Exception ex) {
  }

Das De-Serialisieren der geschriebenen Datei in ein Java-Objekt geschieht ebenso einfach durch die Klasse ObjectInputStream:


  FileInputStream fis = null;
  ObjectInputStream in = null;
  try {
      fis = new FileInputStream("C:/wg/javaobject.ser");
      in = new ObjectInputStream(fis);
      IXMLTest m = (IXMLTest) in.readObject();
      in.close();
      System.out.println(m.getNN());
      System.out.println(m.getVN());
  } catch (Exception ex) {
  }

Arbeiten mit XMLEncoder

Alternativ ist es möglich, das Objekt mit Hilfe der Klasse java.beans.XMLEncoder in ein XML Dokument zu überführen.


IXMLTest m = new Mensch("Wilma", "Wolkenlos", 33, "XML");
java.beans.XMLEncoder x1;
x1 = new java.beans.XMLEncoder(new FileOutputStream("..."));
x1.writeObject(m);
x1.flush();
x1.close();

pic/Java_Objektserialisierung.png

Obwohl das Interface "IXMLTest" keinen Getter und Setter für "hobby" vorgesehen hat, wird das Objekt dennoch vollständig (auch mit der "Hobby"-Information) in XML abgebildet. Das ist auch korrekt, da es sich tatsächlich um eine Instanz der Klasse "Mensch" handelt.


<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_92" class="java.beans.XMLDecoder">
 <object class="Mensch">
  <void property="NN">
   <string>Wolkenlos</string>
  </void>
  <void property="VN">
   <string>Wilma</string>
  </void>
  <void property="a">
   <int>33</int>
  </void>
  <void property="hobby">
   <string>XML</string>
  </void>
 </object>
</java>

Arbeiten mit XMLDecoder

Die Klasse java.beans.XMLDecoder kann diesen Stream wieder einlesen und daraus Objekte der Klasse "Mensch" oder des Interfaces "IXMLTest" generieren. Daher verläuft auch die Typkonvertierung vom Schnittstellenobjekt "IXMLTest" zum Objekt der Klasse "Mensch" problemlos ("Mensch mm = (Mensch) t;").


FileInputStream fi = new FileInputStream("...");
java.beans.XMLDecoder d;
d = new java.beans.XMLDecoder(fi);
IXMLTest t = (IXMLTest) d.readObject();
Mensch mm = (Mensch) t;
Person p = new Person(t);
//Ausgabe

Schauen wir uns nun die zweite Java-Klasse "Person" an, die ebenfalls das Interface "IXMLTest" implementiert und daher dieselben Setter- und Getter-Methoden bereithält wie die Klasse "Mensch" auch.


public class Person implements IXMLTest {
  private String lastname, firstname;
  private int age;
  //Getters, Setters
  //implemented methods
  //Constructors
  public Person(IXMLTest t){
    this.setAge(t.getA());
    this.setFirstname(t.getVN());
    this.setLastname(t.getNN());
  }

Eine Deserialisierung / Dekodierung der XML-Datei auf Objekte der Klasse "Person" kann schwierig werden, obwohl beide Klassen dasselbe Interface ("IXMLTest") implementieren.

Da die Klasse "Person" aber in keiner Vererbungsbeziehung zu "Mensch" steht, ist eine direkte Typkonvertierung nicht möglich. Hilfsweise ist es möglich, das "Person"-Objekt durch einen entsprechenden Copy-Konstruktor zu initialisieren. Dabei geht die Teilinformation "hobby:XML" verständlicherweise verloren, da so etwas in der Klasse "Person" nicht vorgesehen ist.

wg / 29. Januar 2018



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf:

Vorname
Nachname
Mailadresse





JAXB



Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/Java_XMLEncoder.html