Home
Über mich
Blog
Veröffentlichungen
IT-Trainings
Impressum


XML und JAXB

Bei Verwendung von Annotations (javax.xml.bind.annotation) in der "Mensch"-Klasse kann sich eine ähnliche Situation ergeben, wenn die korrespondierende "Person"-Klasse nicht entsprechende Annotations vorhält. Zur Demonstration möchte ich hier die Klasse Mensch noch um Annotations erweitern, die im XML Dokument von Bedeutung sein werden. Unter Anderem sorgt "@XmlRootElement" für die Bezeichnung des Rootelements und Namespaces, "@XmlType(propOrder)" für die Reihenfolge der Elemente bzw. Attribute im XML-Ergebnisdokument. "@XmlAttribute" stellt die Information in Attributschreibweise dar.

import javax.xml.bind.annotation.*;
@XmlRootElement(name = "MENSCH", 
     namespace = "wilfried-grupe.de/jaxb")
@XmlType( propOrder = 
     {"nachname", "NN", "vorname", "VN", "hobby", "alter", "a"})
public class Mensch implements IXMLTest, Serializable {
  private String vorname, nachname;  
  private String _hobby;
  private int alter;
  //Getters, Setters
  //Constructors
  //Implemented methods
  @XmlElement(nillable=true, required=false)
  public String getNachname() {
    return nachname;
  }
  @XmlAttribute(namespace="wilfried-grupe.de/jaxb/demo", 
  required=true, name = "HOBBY")
  public String getHobby() {
    return this._hobby;
  }
  @XmlAttribute(namespace="wilfried-grupe.de/jaxb/demo", name = "ALTER1")
  public int getAlter() {
    return alter;
  }
  @XmlAttribute(namespace="wilfried-grupe.de/jaxb/demo", name = "ALTER2")
  public int getA() {
    return this.getAlter();
  }
}

Wie vorhin, generieren wir ein Objekt der Klasse mit Hilfe von JAXB und "marshallen" es in eine Datei.

  Mensch m = new Mensch("Wilma", "Wolkenlos", 33, "XML");
  try {
    JAXBContext context;
    context = JAXBContext.newInstance(Mensch.class);
    Marshaller mm = context.createMarshaller();
    mm.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    mm.marshal(m, new File("C:/wg/jaxb_demo.xml"));
  } catch (PropertyException e) {
  } catch (JAXBException e) {
  }

Im Ergebnis finden wir ein XML Dokument mit mehreren Namespaces, Attributen und Elementen.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:MENSCH 
  xmlns:ns2="wilfried-grupe.de/jaxb/demo" 
  xmlns:ns3="wilfried-grupe.de/jaxb" 
  ns2:HOBBY="XML" 
  ns2:ALTER1="33" 
  ns2:ALTER2="33">
    <nachname>Wolkenlos</nachname>
    <NN>Wolkenlos</NN>
    <vorname>Wilma</vorname>
    <VN>Wilma</VN>
</ns3:MENSCH>

Anmerkungen zu den Annotations (z.B. "@XmlElement(nillable=false, required=false)"):

Wird dieses XML Dokument "unmarshalled" und in ein Objekt der Klasse Mensch (dann ist der Zugriff auf "m.getHobby()" möglich) oder in ein Schnittstellenobjekt "IXMLTest" überführt, dann ist die Ausführung problemlos.

  try {
    JAXBContext context;
    context = JAXBContext.newInstance(Mensch.class);
    Unmarshaller um = context.createUnmarshaller();
    IXMLTest m = (IXMLTest) um.unmarshal(new FileReader(
      "C:/wg/jaxb_demo.xml"));
    //System.out.println(m.getHobby());
    System.out.println(m.getVN());
    System.out.println(m.getNN());
    System.out.println(m.getA());
  } catch (FileNotFoundException e) {
  } catch (JAXBException e) {
  }

Ein Casten des generierten "Mensch"-Objekts auf "Person" läuft jedoch auf einen Fehler:

Person m = (Person) um.unmarshal(new FileReader(...));
Exception in thread "main" java.lang.ClassCastException: 
Mensch cannot be cast to Person

Ebenso erhalten wir einen Fehler, wenn der JAXBContext auf die Klasse "Person" ausgerichtet ist, der XML-Stream aber unverändert ist:

JAXBContext context = JAXBContext.newInstance(Person.class);
Person m = (Person) um.unmarshal(new FileReader(...));
unerwartetes Element (URI:"wilfried-grupe.de/jaxb", lokal:"MENSCH"). 
Erwartete Elemente sind (none)

qrpic/Datenaustausch2.jpg

wg / 14. Oktober 2017




Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf (info10@wilfried-grupe.de).



Vielen Dank für Ihr Interesse an meiner Arbeit.


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

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