EN · DE · RU · FR · ES

#754: XmlField.java

projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlField.java Java-Annotation — zentrale Feld-Annotation des XmlStream-Frameworks. 92 Zeilen. @Target(FIELD), @Retention(RUNTIME). Quelle: projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlField.java 92 Zeilen · 17 Code · 63 Kommentare · 12 leer
Zweck: Die zentrale Annotation des XmlStream-Frameworks — entspricht JAXBs @XmlElement, @XmlAttribute, XStreams @XStreamAlias und @XStreamAsAttribute, alles in einer Annotation vereint. Markiert ein Java-Feld als serialisierbar nach XML und steuert genau, wie es geschrieben wird. Angewendet auf Feldebene (@Target(FIELD)) und zur Laufzeit über Reflektion verfügbar (@Retention(RUNTIME)) — so entdecken XmlObjectWriter und XmlObjectReader serialisierbare Felder.

8 Annotation-Attribute

alias() — XML-Element-/Attributname

Überschreibt den Feldnamen während der Serialisierung. Ohne Alias: private String firstName → Tag <firstName>. Mit Alias: @XmlField(alias="first-name") → Tag <first-name>. Nützlich, wenn das XML-Format einem externen Schema entsprechen muss oder wenn ein Java-Feldname mit einem reservierten XML-Wort kollidiert.

asAttribute() und asElement() — Attribut vs. Element

Steuert, ob der Wert als XML-Attribut (kompakt) oder als Element (strukturiert) serialisiert wird:

<!-- Als Attribut: -->
<user id="42" name="John"/>

<!-- Als Element: -->
<user><id>42</id><name>John</name></user>

Wichtige Nuance aus dem Javadoc: "asAttribute=false hat keine Wirkung (bitte stattdessen asElement=true verwenden)" und umgekehrt. Das bedeutet, false ist keine Verneinung — es bedeutet "Standard belassen", was durch globale Einstellungen in XmlObjectWriter.asAttributeAsDefault() überschrieben werden kann. Um eine Attribut-Serialisierung sicherzustellen, verwenden Sie asAttribute=true. Um ein Element sicherzustellen, verwenden Sie asElement=true.

defaultDoubleValue / defaultIntValue / defaultStringValue / defaultBooleanValue — XML-Kompression

Wenn der Feldwert dem deklarierten Standard entspricht, wird er NICHT nach XML serialisiert. Dies ist ein Kompressionsmechanismus: Typische Standardwerte belegen keinen Platz in der Ausgabe. Während der Deserialisierung erhalten fehlende Tags den Standardwert. Die magischen Zahlen aus XmlConstants (#751) dienen als "nicht gesetzt"-Sentinel für int- und String-Standardwerte. Für boolean ist der Standard false (der häufigste Wert). Für double ist der Standard NaN ("nicht gesetzt").

asCDATA() — Schutz von Sonderzeichen

Wenn true, wird der String-Wert in einen XML-<![CDATA[...]]>-Block eingeschlossen. Erforderlich für Felder, die <, >, &-Zeichen enthalten können — z. B. HTML in Beschreibungsfeldern oder SQL in Logs. Ohne CDATA müssten diese Zeichen als &lt;, &gt;, &amp; maskiert werden, was das XML unlesbar macht.

Laufzeitnutzung

  1. XmlObjectWriter durchläuft während der Serialisierung alle Felder eines Objekts per Reflektion
  2. Für jedes Feld wird auf @XmlField (und das Fehlen von @XmlOmitField) geprüft
  3. Wenn vorhanden, werden die Parameter ausgelesen: Alias (Tag-Name), asAttribute (Format), default* (Skip-Logik), asCDATA (Format)
  4. Ruft den entsprechenden Converter auf, um den Feldwert in einen String umzuwandeln
  5. XmlObjectReader macht das Gegenteil: Liest Tag/Attribut aus XML, findet das passende Feld anhand des Namens oder Alias, ruft Converter für die Rückumwandlung auf

Vergleich mit XStream und JAXB

FunktionXmlFieldXStreamJAXB
Feld-Aliasalias="name"@XStreamAlias("name")@XmlElement(name="name")
Attribut vs. ElementasAttribute=true@XStreamAsAttribute@XmlAttribute
Feldausschluss@XmlOmitField@XStreamOmitField@XmlTransient
StandardwertdefaultIntValue=0❌ keiner❌ keiner
CDATAasCDATA=true❌ keiner❌ keiner
Format-Versionierung✅ über XmlObject❌ keiner❌ keiner
XmlField + XmlStream bieten mehr Kontrolle über das XML-Format als XStream, erfordern jedoch manuelle Annotation. XStream "funktioniert einfach" ohne Annotationen, erzeugt aber weniger kontrolliertes XML. Die Wahl von XmlStream für den Datenexport wurde speziell durch die Notwendigkeit von Formatkontrolle und Versionierung bestimmt.

Git-Verlauf

868d6abb7 2025 → 2026 (Aktualisierung des Copyright-Jahres)
63081666f Quelldatei-Header: 2024→2025
b6092df09 Copyright 2023 → 2024
ab45d51fa Copyright 2001-2022 → 2001-2023
5f7ef41b8 Copyright 2021 → 2022
cd27dd997 Paket xstream → xmlstream (umbenannt, um Verwechslung mit der XStream-Bibliothek zu vermeiden)
ceb63e8a1 Quellcode-Header: (C) 2001-2021
7c79f1922 Copyright des Quell-Headers → 2020
32f634b88 Importe optimiert
dd5ca38ac Copyright aller Java-Datei-Header aktualisiert oder erstellt
9ebb88522 Erster Commit
Die Annotation-Attribute sind seit dem ersten Commit stabil. Nur Copyright-Header, Import-Optimierung (32f634b88) und die Paketumbenennung haben diese Datei berührt. Das auskommentierte Attribut implementationClass() deutet darauf hin, dass der Autor ein Interface-zu-Implementierungs-Mapping auf Feldebene in Betracht gezogen hat, sich aber dafür entschied, es stattdessen in XmlObjectReader.addImplementationMapping() zu behandeln.