{"id":628,"date":"2010-04-27T11:20:41","date_gmt":"2010-04-27T09:20:41","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/2010\/04\/die-ersten-schritte-mit-jaxb\/"},"modified":"2010-04-27T11:59:43","modified_gmt":"2010-04-27T09:59:43","slug":"die-ersten-schritte-mit-jaxb","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2010\/04\/die-ersten-schritte-mit-jaxb\/","title":{"rendered":"Die ersten Schritte mit JAXB"},"content":{"rendered":"<p>JAXB ist eine API zum \u00dcbertragen von Objektzust\u00e4nden auf XML-Dokumente und umgedreht. Anders als eine manuelle Abbildung von Java-Objekten auf XML-Dokumente oder das Parsen von XML-Strukturen und \u00dcbertragen der XML-Elemente auf Gesch\u00e4ftsobjekte arbeitet JAXB\u00a0automatisch. Die \u00dcbertragungsregeln definieren Annotationen, die Entwickler selbst an die JavaBeans setzten k\u00f6nnen, aber JavaBeans werden gleich zusammen mit den Annotationen von einem Werkzeug aus deiner XML-Schema-Datei generiert.<\/p>\n<p>Java 6 integriert JAXB 2.0, und das JDK 6 Update 4 \u2013 sehr ungew\u00f6hnlich f\u00fcr ein Update \u2013 aktualisiert auf JAXB 2.1.<\/p>\n<h3>1.1.1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Bean f\u00fcr JAXB aufbauen<\/h3>\n<p>Wir wollen einen Player deklarieren, und JAXB soll ihn anschlie\u00dfend in ein XML-Dokument \u00fcbertragen.<\/p>\n<p>com\/tutego\/insel\/xml\/jaxb\/Player.java, Player<\/p>\n<p><strong>@XmlRootElement<\/strong><\/p>\n<p>class Player<\/p>\n<p>{<\/p>\n<p>private String name;<\/p>\n<p>private Date\u00a0\u00a0 birthday;<\/p>\n<p>public String getName()<\/p>\n<p>{<\/p>\n<p>return name;<\/p>\n<p>}<\/p>\n<p>public void setName( String name )<\/p>\n<p>{<\/p>\n<p>this.name = name;<\/p>\n<p>}<\/p>\n<p>public void setBirthday( Date birthday )<\/p>\n<p>{<\/p>\n<p>this.birthday = birthday;<\/p>\n<p>}<\/p>\n<p>public Date getBirthday()<\/p>\n<p>{<\/p>\n<p>return birthday;<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>Die Klassen-Annotation @XmlRootElement\u00a0ist an der JavaBean n\u00f6tig, wenn die Klasse das Wurzelelement eines XML-Baums bildet. Die Annotation stammt aus dem Paket javax.xml.bind.annotation.<\/p>\n<h3>1.1.2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 JAXBContext und die Marshaller<\/h3>\n<p>Ein kleines Testprogramm baut eine Person auf bildet sie dann in XML ab \u2013 die Ausgabe der Abbildung kommt auf dem Bildschirm.<\/p>\n<p>com\/tutego\/insel\/xml\/xml\/jaxb\/PlayerMarshaller.java, main()<\/p>\n<p>Player johnPeel = new Player();<\/p>\n<p>johnPeel.setName( &#8222;John Peel&#8220; );<\/p>\n<p>johnPeel.setBirthday( new GregorianCalendar(1939,Calendar.AUGUST,30).getTime() );<\/p>\n<p><strong>JAXBContext context = JAXBContext.newInstance( Player.class );<\/strong><\/p>\n<p><strong>Marshaller m = context.createMarshaller();<\/strong><\/p>\n<p><strong>m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );<\/strong><\/p>\n<p><strong>m.marshal( johnPeel, System.out );<\/strong><\/p>\n<p>Nach dem Lauf kommt auf den Schirm:<\/p>\n<p>&lt;?xml version=&#8220;1.0&#8243; encoding=&#8220;UTF-8&#8243; standalone=&#8220;yes&#8220;?&gt;<\/p>\n<p>&lt;player&gt;<\/p>\n<p>&lt;birthday&gt;1939-08-30T00:00:00+01:00&lt;\/birthday&gt;<\/p>\n<p>&lt;name&gt;John Peel&lt;\/name&gt;<\/p>\n<p>&lt;\/player&gt;<\/p>\n<p>Alles bei JAXB beginnt mit der zentralen Klasse JAXBContext. Die statische Methode JAXBContext.newInstance() erwartet standardm\u00e4\u00dfig eine Aufz\u00e4hlung der Klassen, die JAXB behandeln soll. Der JAXBContext erzeugt den Marshaller\u00a0zum Schreiben und Unmarshaller\u00a0zum Lesen. Die Fabrikmethode createMarshaller() liefert einen Schreiberling, der mit marshal() das Wurzelobjekt in einen Datenstrom schreibt. Das zweite Argument von marshal() ist unter anderem ein OutputStream (wie System.out in unserem Beispiel), Writer oder File-Objekt.<\/p>\n<p>JAXB beachtet standardm\u00e4\u00dfig alle Bean-Properties, also birthday und name, und nennt die XML-Elemente nach den Properties.<\/p>\n<h3>1.1.3\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ganze Objektgrafen schreiben und lesen<\/h3>\n<p>JAXB bildet nicht nur das zu schreiben Objekt ab, sondern auch rekursiv alle referenzierten Unterobjekte. Wir wollen den Spieler dazu in einen Raum setzen und den Raum in XML abbilden. Dazu muss der Raum die Annotation @XmlRootElement bekommen und bei Player kann sie entfernt werden, wenn nur der Raum selbst aber kleine Player als Wurzelobjekte zum Marshaller kommen.<\/p>\n<p>com\/tutego\/insel\/xml\/xml\/jaxb\/Room.java, Room<\/p>\n<p>@XmlRootElement( <strong>namespace = &#8222;http:\/\/tutego.com\/&#8220;<\/strong> )<\/p>\n<p>public class Room<\/p>\n<p>{<\/p>\n<p>private List&lt;Player&gt; players = new ArrayList&lt;Player&gt;();<\/p>\n<p><strong> @XmlElement( name = &#8222;player&#8220; )<\/strong><\/p>\n<p>public List&lt;Player&gt; getPlayers()<\/p>\n<p>{<\/p>\n<p>return players;<\/p>\n<p>}<\/p>\n<p>public void setPlayers( List&lt;Player&gt; players )<\/p>\n<p>{<\/p>\n<p>this.players = players;<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>Zwei Annotationen kommen vor: Da Room der Start des Objektgrafen ist, tr\u00e4gt es @XmlRootElement. Als Erweiterung ist das Element namespace f\u00fcr den Namensraum gesetzt, da bei eigenen XML-Dokumenten immer ein Namensraum genutzt werden soll. Weiterhin ist eine Annotation @XmlElement\u00a0am Getter getPlayers() platziert, um den Namen des XML-Elements zu \u00fcberschreiben, damit das XML-Element nicht &lt;player<strong>s<\/strong>&gt; hei\u00dft, sondern &lt;player&gt;.<\/p>\n<p>Kommen wir abschlie\u00dfend zu einem Beispiel, das einen Raum mit 2 Spielern aufbaut, und diesen Raum dann in eine XML-Datei schreibt. Statt allerdings JAXBContext direkt zu nutzen und einen Marshaller zum Schreiben und Unmarshaller zum Lesen zu erfragen, kommt im zweiten Beispiel die Utility-Klasse JAXB zum Einsatz, die ausschlie\u00dflich statische \u00fcberladene marshal() und unmarshal() Methoden anbietet.<\/p>\n<p>Player john = new Player();<\/p>\n<p>john.setName( &#8222;John Peel&#8220; );<\/p>\n<p>Player tweet = new Player();<\/p>\n<p>tweet.setName( &#8222;Zwitscher Zoe&#8220; );<\/p>\n<p>Room room = new Room();<\/p>\n<p>room.setPlayers( Arrays.asList( john, tweet ) );<\/p>\n<p>File file = File.createTempFile( &#8222;room-jaxb-&#8222;, &#8222;.xml&#8220; );<\/p>\n<p><strong>JAXB.marshal( room, file );<\/strong><\/p>\n<p><strong>Room room2 = JAXB.unmarshal( file, Room.class );<\/strong><\/p>\n<p>System.out.println( room2.getPlayers().get( 0 ).getName() ); \/\/ John Peel<\/p>\n<p>file.deleteOnExit();<\/p>\n<p>Falls etwas beim Schreiben oder Lesen misslingt, werden die vorher gepr\u00fcften Ausnahmen in einer DataBindingException ummantelt, die eine RuntimeException ist.<\/p>\n<p>Die Ausgabe ist:<\/p>\n<p>&lt;?xml version=&#8220;1.0&#8243; encoding=&#8220;UTF-8&#8243; standalone=&#8220;yes&#8220;?&gt;<\/p>\n<p>&lt;ns2:room xmlns:ns2=&#8220;http:\/\/tutego.com\/&#8220;&gt;<\/p>\n<p>&lt;player&gt;<\/p>\n<p>&lt;name&gt;John Peel&lt;\/name&gt;<\/p>\n<p>&lt;\/player&gt;<\/p>\n<p>&lt;player&gt;<\/p>\n<p>&lt;name&gt;Zwitscher Zoe&lt;\/name&gt;<\/p>\n<p>&lt;\/player&gt;<\/p>\n<p>&lt;\/ns2:room&gt;<\/p>\n<p>Da beim Spieler das Geburtsdatum nicht gesetzt war (null wird referenziert), wird es auch nicht in XML abgebildet.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>JAXB ist eine API zum \u00dcbertragen von Objektzust\u00e4nden auf XML-Dokumente und umgedreht. Anders als eine manuelle Abbildung von Java-Objekten auf XML-Dokumente oder das Parsen von XML-Strukturen und \u00dcbertragen der XML-Elemente auf Gesch\u00e4ftsobjekte arbeitet JAXB\u00a0automatisch. Die \u00dcbertragungsregeln definieren Annotationen, die Entwickler selbst an die JavaBeans setzten k\u00f6nnen, aber JavaBeans werden gleich zusammen mit den Annotationen von [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[11],"tags":[],"class_list":["post-628","post","type-post","status-publish","format-standard","hentry","category-insel"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/628","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=628"}],"version-history":[{"count":2,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/628\/revisions"}],"predecessor-version":[{"id":629,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/628\/revisions\/629"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=628"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=628"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=628"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}