Blog

JAXB optimieren, um besseren Code zu erzeugen

Maarten Winkels

Aktualisiert Oktober 23, 2025
3 Minuten

JAXB kann eine echte Zeitersparnis sein, wenn Sie an einem Projekt arbeiten, das XSD zur Beschreibung von in Java implementierten Schnittstellen verwendet. Manchmal entspricht der generierte Code jedoch nicht dem Standard. Ich bin auf ein Problem gestoßen, das sehr verbreitet zu sein scheint, und habe im Internet eine sehr elegante Lösung dafür gefunden.

Als ich gestern an dem XML-Schema für Document arbeitete, musste ich mich entscheiden, ob ich Sammlungen in ein umgebendes Element einpacken sollte, etwa so: [xml] <Dokument> ... <Antworten> <Antwort> ... </Reply> <Antwort> ... </Reply> ... </Replies> ... </Document> [/xml] oder ich würde einfach eine Folge von <Antwort>-Elementen direkt unter Document haben. Ich denke, dass der allgemeine Konsens darin besteht, Wrapping-Elemente zu verwenden, aber ich beschloss, das Design auf eine andere Maßnahme zu stützen: Wie würde der (Java-)Code aussehen, der von JAXB aus dem Schema generiert würde. Nachdem ich das maven-jaxb-plugin in das Projekt konfiguriert hatte (was wirklich einfach war und es über M2Eclipse sofort in Eclipse integriert wurde), war der Java-Code ein wenig enttäuschend: Für jede Sammlung erhielt ich die folgende Struktur: [java] class Document { @XmlElement(name = "Antworten") private Replies replies; public Replies getReplies() { return replies; } public class Replies() { @XmlElement(name = "Antwort") private List<Reply> reply; public List<Reply> getReply() { return reply; } } } [/java] Dies würde zu folgendem Nutzungsmuster führen: [java] Document doc; ... doc.getReplies().getReply().add(new Reply(...)); [/java] was meiner Meinung nach ziemlich schrecklich ist. Ich würde erwarten, dass es eine einfache Sammlungsstruktur gibt: [java] Document doc; ... doc.getReplies().add(new Reply(...)); [/java] Aber egal, ob ich das Wrapping-Element verwenden würde oder nicht, ich würde trotzdem die zusätzliche Klasse erhalten. Es gibt eine JAXB-Annotation, die in dieser Situation hilft: [java] @XmlElementWrapper(name = "replies") @XmlElement(name = "reply") protected List<Reply> replies; [/java] Und das ist genau das, was wir wollen, aber wie sage ich dem JAXB-Codegenerator, dass er diese Annotation verwenden soll? Nach einigem Herumgoogeln fand ich diesen Blogbeitrag(www.conspicio.dk/blog/bjarne/jaxb-xmlelementwrapper-plugin), der eine Lösung bietet, indem er ein benutzerdefiniertes Plugin für XJB (den JAXB-Codegenerator) verwendet. Die Konfiguration dieses Plugins in Maven war recht einfach:

  1. Fügen Sie das Plugin-Jar (das leider nicht in einem Maven-Repository verfügbar war) zu den maven-jaxb-plugin-Abhängigkeiten hinzu.
  2. Fügen Sie der Plugin-Konfiguration ein <args>-Element mit der Option -Xxew hinzu, um das Plugin zu aktivieren.

Die endgültige Maven-Konfiguration sieht wie folgt aus: [xml] <Plugin> <groupId>com.sun.tools.xjc.maven2</groupId> <artifactId>maven-jaxb-plugin</artifactId> <Hinrichtungen> <Ausführung> <id>jaxb-generate</id> <Ziele> <Ziel>erzeugen</Ziel> </goals> </execution> </executions> <Konfiguration> <includeSchemas> <includeSchema>xsd/Document.xsd</includeSchema> </includeSchemas> <strikt>true</strikt> <verbose>true</verbose> <args>-Xxew</args> </configuration> <Abhängigkeiten> <Abhängigkeit> <groupId>xew</groupId> <artifactId>xew</artifactId> <Version>1.0.0</version> <Geltungsbereich>Laufzeit</Geltungsbereich> </dependency> </dependencies> </plugin> [/xml] Der generierte Code verwendet jetzt eine einfache Sammlung, so dass er viel brauchbarer aussieht. Ein letztes Problem ist, dass die generierte Klasse Replies, die jetzt nicht mehr verwendet wird, nicht aus dem Code entfernt wird: Eine kleine Aufräumaktion, die den Entwicklern des Plugins wohl entfallen ist.

Verfasst von

Maarten Winkels

Contact

Let’s discuss how we can support your journey.