EN · DE · RU · FR · ES

#759: XmlOmitField.java

projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlOmitField.java Java-Marker-Annotation — schließt ein Feld von der XmlStream-XML-Serialisierung aus. Quelle: projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlOmitField.java 39 Zeilen · 9 Code · 26 Kommentare · 4 leer
Zweck: Eine parameterlose Marker-Annotation, die dem XmlStream-Framework mitteilt, ein Feld während der XML-Serialisierung und -Deserialisierung zu überspringen. Sie ist das XmlStream-Äquivalent zum Java-transient-Schlüsselwort und zu JAXBs @XmlTransient, jedoch ausschließlich auf das ProjectForge-XmlStream-Framework beschränkt – das Feld bleibt für die Java-Serialisierung, JPA-Persistenz und andere Subsysteme intakt.

Architektur

Die Annotation selbst ist minimal – 3 Codezeilen, @Target(FIELD), @Retention(RUNTIME). Ihre Stärke liegt in den Konsumenten, die auf ihr Vorhandensein prüfen:

XmlObjectWriter.writeField() (#758, Zeile ~242): if (field.isAnnotationPresent(XmlOmitField.class)) continue;
XmlObjectReader.read() (#757, Zeile ~471): überspringt mit @XmlOmitField annotierte Felder während der Deserialisierung

Die Annotation selbst enthält keine Logik – sie ist ein reiner Marker, der reflektiv vom Lese-/Schreib-Paar konsumiert wird.

Warum eine separate Annotation anstelle von transient?

Das Java-transient-Schlüsselwort schließt ein Feld von allen Serialisierungsmechanismen aus – Java-Serialisierung, XStream, XmlStream, JSON-Mapper, alles. Das ist oft zu weit gefasst:

Szenario: Ein Feld wie computedHash sollte in der HTTP-Sitzung zwischengespeichert werden (Java-Serialisierung), darf aber nicht in XML-Exporten erscheinen (verschwenderisch, irreführend).

Lösung: Machen Sie das Feld nicht-transient (damit es an der Java-Sitzungsserialisierung teilnimmt) und annotieren Sie es mit @XmlOmitField (damit XmlStream es überspringt). Dies ermöglicht eine pro-Framework-Kontrolle über die Serialisierungssichtbarkeit.

Sicherheitsbeispiel: password in PFUserDO. Das Feld ist transient (Sitzungssicherheit) UND mit @XmlOmitField annotiert (XML-Sicherheit). Selbst wenn jemand transient zu Debugging-Zwecken entfernt, bietet die Annotation eine zweite Barriere, die verhindert, dass Passwörter in XML-Exporte gelangen.

Abgrenzung zu @XmlField(defaultValue=...)

MechanismusWann wird das Feld übersprungenAnwendungsfall
@XmlOmitFieldImmer – unabhängig vom WertPasswörter, berechnete Felder, temporärer Zustand, sensible Daten
@XmlField(defaultIntValue=0)Bedingt – nur wenn der Wert dem Standard entsprichtGrößenoptimierung: Nullwerte, leere Zeichenketten, Nullen auslassen
Der Unterschied ist semantisch: @XmlOmitField sagt „Dieses Feld hat nichts in XML zu suchen“, während @XmlField(defaultValue=...) sagt „Dieses Feld ist manchmal redundant – überspringe es, wenn es das ist“. Das eine ist eine harte Richtlinie, das andere eine weiche Optimierung.

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 Optimierte Importe
dd5ca38ac Copyright aller Java-Datei-Header erstellt oder aktualisiert
9ebb88522 Erster Commit
Die Annotation ist seit dem ersten Commit unverändert geblieben – nur Copyright-Header und eine Paketumbenennung (xstreamxmlstream). Diese Stabilität spiegelt ihr Design wider: Eine Marker-Annotation ohne Parameter hat keine beweglichen Teile, die brechen könnten. Die einzig nennenswerte Änderung war cd27dd997, die das Paket von xstream in xmlstream umbenannte, um eine Namensraumkollision mit der XStream-Bibliothek (com.thoughtworks.xstream) zu vermeiden.

XmlStream-Annotationen-Trio

AnnotationDateiRolle
@XmlField#755Deklariert ein Feld zur Serialisierung mit Name, Typ, Standardwert, Format, Reihenfolge
@XmlObject#756Deklariert eine Klasse als XML-serialisierbar mit Alias
@XmlOmitField#759Schließt ein Feld vollständig von der Serialisierung aus
Zusammen bilden diese drei Annotationen die vollständige Konfigurationsoberfläche des XmlStream-Frameworks. @XmlObject aktiviert eine Klasse für die Serialisierung, @XmlField konfiguriert einzelne Felder und @XmlOmitField deaktiviert Felder selektiv. Dies ist einfacher als JAXB (das ~20 Annotationen hat) und expliziter als der reine Konventionsansatz von XStream.