Fachlicher Vertrag: unverändert zu erhalten
- Extrahierte Fachwerte bleiben identisch.
- Externe Entitäten und DTD-Zugriffe sind deaktiviert.
- Speicherverbrauch skaliert mit Streaming statt Dokumentgröße.
DOM lädt vollständigen Objektbaum wird nachvollziehbar in StAX verarbeitet Streaming-Events überführt. Die Akte zeigt nicht nur das Ziel, sondern die tatsächlichen Dateien, APIs, Dependencies, Codebelege, Tests, Risiken und Cutover-Schritte.
| Dimension | Legacy | Modern | Migrationskonsequenz |
|---|---|---|---|
| Programmiermodell | imperativ / ohne Framework-Annotationen | explizite Java-Abstraktionen | Annotationen und Containerfunktionen werden nur dort eingesetzt, wo sie eine konkrete technische Verantwortung übernehmen. |
| Abhängigkeiten | 1 direkte Dependencies | 1 direkte Dependencies | 0 neu, 0 entfernt; Versionen und transitive Auswirkungen im erfolgreichen Online-Build prüfen. |
| Öffentliche API | 1 erkannte Methoden | 1 erkannte Methoden | Methoden werden nach fachlicher Rolle gemappt; reine Bootstrap- und Framework-Methoden sind kein fachlicher Vertrag. |
| Datenmodell | class DomOrderReader | class StaxOrderReader | Feldnamen, IDs, Null-Semantik, Gleichheit und Serialisierungsform werden separat regressionstestet. |
| Fehlerverhalten | Legacy-Exceptions und Rückgabewerte | explizitere Fach-/Framework-Fehlerabbildung | Fehler dürfen nicht nur technisch übersetzt werden; Status, Ursache, Retrybarkeit und Client-Vertrag müssen erhalten oder versioniert werden. |
| Tests | Bestands- und Golden-Master-Tests | Unit-, Slice-, Contract- und Integrationstests | Der Modern-Pfad wird zuerst gegen denselben fachlichen Vektor geprüft und danach um neue technische Risiken ergänzt. |
| Betrieb | Legacy-Start/Lifecycle | modernes Packaging, Health und externe Konfiguration | Golden-Master-Dokumente und negative XXE-/Malformed-Tests sind obligatorisch. |
| Rollback | Legacy-Artefakt bleibt unverändert | Modern-Artefakt getrennt deploybar | Kein Rollback über Datenverlust: Schema, Nachrichten und verschlüsselte Daten müssen rückwärtslesbar oder durch Dual-Read abgesichert sein. |
XXE, entity expansion and malformed XML
XXE-negative, namespace, large input and error-position tests
Die Zuordnung ist semantisch: Eine Legacy-Klasse kann in mehrere moderne Rollen zerlegt werden.
| Legacy-Rolle / Datei | Modern-Rolle / Datei | Bedeutung |
|---|---|---|
| DomOrderReader.java | StaxOrderReader.java | Vollständiger DOM-Baum wird Streaming Reader. |
| Datei | Typ | Annotationen | öffentliche API | Pattern | Zeilen |
|---|---|---|---|---|---|
| DomOrderReader.java | class DomOrderReader | — | double total(InputStream in) | Parser | 17 |
| Datei | Typ | Annotationen | öffentliche API | Pattern | Zeilen |
|---|---|---|---|---|---|
| StaxOrderReader.java | class StaxOrderReader | — | double total(InputStream inputStream) | Iterator | 28 |
| Status | Dependency | Version | Scope | Prüfung |
|---|---|---|---|---|
| BEIBEHALTEN | org.junit.jupiter:junit-jupiter | BOM/Parent → BOM/Parent | test → test | Gemeinsame Dependency; Version und Scope im effektiven POM prüfen. |
Die folgenden Ausschnitte stammen direkt aus den enthaltenen Projekten. Dadurch ist sichtbar, welche Verantwortung tatsächlich verschoben wurde.
Migrationsbedeutung: Vollständiger DOM-Baum wird Streaming Reader.
projects/30-xml-parsers/legacy/src/main/java/at/aydin/lab/xmlparser/legacy/DomOrderReader.java
package at.aydin.lab.xmlparser.legacy;
import javax.xml.parsers.*;
import java.io.*;
// Design Pattern: Parser
// Zweck: DOM bietet komfortablen Objektbaum, lädt aber das komplette Dokument.
public final class DomOrderReader {
public double total(InputStream in) throws Exception {
var f = DocumentBuilderFactory.newInstance();
f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
var nodes = f.newDocumentBuilder().parse(in).getElementsByTagName("total");
double sum = 0;
for (int i = 0; i < nodes.getLength(); i++) sum += Double.parseDouble(nodes.item(i).getTextContent());
return sum;
}
}
projects/30-xml-parsers/modern/src/main/java/at/aydin/lab/xmlparser/modern/StaxOrderReader.java
package at.aydin.lab.xmlparser.modern;
import java.io.InputStream;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
// Design Pattern: Iterator
// Zweck: Pull-Parsing verarbeitet große Dokumente ereignisweise mit konstantem Speicherbedarf.
public final class StaxOrderReader {
public double total(InputStream inputStream) throws Exception {
XMLInputFactory factory = XMLInputFactory.newFactory();
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
factory.setProperty("javax.xml.stream.isSupportingExternalEntities", false);
XMLStreamReader reader = factory.createXMLStreamReader(inputStream);
double sum = 0;
while (reader.hasNext()) {
boolean totalElement = reader.next() == XMLStreamConstants.START_ELEMENT
&& reader.getLocalName().equals("total");
if (totalElement) {
sum += Double.parseDouble(reader.getElementText());
}
}
reader.close();
return sum;
}
}
--- DomOrderReader.java
+++ StaxOrderReader.java
@@ -1,17 +1,28 @@
-package at.aydin.lab.xmlparser.legacy;
+package at.aydin.lab.xmlparser.modern;
-import javax.xml.parsers.*;
-import java.io.*;
+import java.io.InputStream;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamReader;
-// Design Pattern: Parser
-// Zweck: DOM bietet komfortablen Objektbaum, lädt aber das komplette Dokument.
-public final class DomOrderReader {
- public double total(InputStream in) throws Exception {
- var f = DocumentBuilderFactory.newInstance();
- f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
- var nodes = f.newDocumentBuilder().parse(in).getElementsByTagName("total");
+// Design Pattern: Iterator
+// Zweck: Pull-Parsing verarbeitet große Dokumente ereignisweise mit konstantem Speicherbedarf.
+public final class StaxOrderReader {
+ public double total(InputStream inputStream) throws Exception {
+ XMLInputFactory factory = XMLInputFactory.newFactory();
+ factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+ factory.setProperty("javax.xml.stream.isSupportingExternalEntities", false);
+
+ XMLStreamReader reader = factory.createXMLStreamReader(inputStream);
double sum = 0;
- for (int i = 0; i < nodes.getLength(); i++) sum += Double.parseDouble(nodes.item(i).getTextContent());
+ while (reader.hasNext()) {
+ boolean totalElement = reader.next() == XMLStreamConstants.START_ELEMENT
+ && reader.getLocalName().equals("total");
+ if (totalElement) {
+ sum += Double.parseDouble(reader.getElementText());
+ }
+ }
+ reader.close();
return sum;
}
}
| ID | Ebene | Prüfung | erforderlicher Nachweis |
|---|---|---|---|
| 30-XML-PARSERS-A01 | Integration/Contract | Golden-Master-Werte stimmen. | Automatisierter Test und CI-Protokoll |
| 30-XML-PARSERS-A02 | Integration/Contract | XXE-/DTD-Test bleibt blockiert. | Automatisierter Test und CI-Protokoll |
| 30-XML-PARSERS-A03 | Integration/Contract | Große Datei überschreitet definiertes Speicherlimit nicht. | Automatisierter Test und CI-Protokoll |
| 30-XML-PARSERS-A04 | Integration/Contract | Malformed XML enthält brauchbare Position. | Automatisierter Test und CI-Protokoll |
| 30-XML-PARSERS-A05 | Integration/Contract | Namespaces werden korrekt behandelt. | Automatisierter Test und CI-Protokoll |
| 30-XML-PARSERS-T01 | Unit | Fachlogik ohne Container oder externen Dienst testen. | Unit-Test |
| 30-XML-PARSERS-T02 | Regression | Legacy- und Modern-Ergebnis für denselben Golden-Master-Vektor vergleichen. | Vergleichsreport |
| 30-XML-PARSERS-T03 | Negative | Fehlerhafte, leere und grenzwertige Eingaben prüfen. | Negativtest |
| 30-XML-PARSERS-T04 | Operations | Start, Health, Shutdown und Konfigurationsfehler prüfen. | Deployment-/Startprotokoll |
| 30-XML-PARSERS-T05 | Security | XXE, externe Entitäten und malformed XML negativ testen. | Security-Test |
| 30-XML-PARSERS-F01 | Fokus | XXE-negative, namespace, large input and error-position tests | Modulspezifischer Testreport |
| Risiko | Auswirkung | Gegenmaßnahme | Gate |
|---|---|---|---|
| XXE, entity expansion and malformed XML | NIEDRIG | XXE-negative, namespace, large input and error-position tests | vor Cutover |
Keine zusätzlichen Ressourcen.
Parser-Fassade kann DOM oder StAX anhand Feature Flag wählen; das fachliche Ergebnisobjekt bleibt identisch.