@XmlRootElement(name = "Vertrag")
public class Vertrag {
@XmlElement(name = "wohnflaeche", nillable = true)
private Integer wohnflaeche;
@XmlJavaTypeAdapter(value = LocalDateAdapter.class) (1)
@XmlAttribute(name = "verkaufsStart")
private LocalDate verkaufsStart;
@XmlElement(name = "Deckung", type = org.faktorips.beispiel.modell.Deckung.class)
@XmlElementWrapper(name = "Deckungen")
private List<Deckung> deckungen;
@XmlJavaTypeAdapter(value = ProductConfigurationXmlAdapter.class)
@XmlAttribute(name = "product-component.id")
private ProductConfiguration productConfiguration;
// [...]
}
Generatoroptionen
JAXB / Jakarta Support
Ist die Einstellung generateJaxbSupport
auf ClassicJXB
, bzw. JakartaXmlBinding
gesetzt, werden in allen Vertragsklassen JAXB-Annotationen generiert.
JAXB[1] ist ein Framework, um Objekte als XML zu de-/serialisieren. Bis Java (EE) 8 war JAXB mit dem Package javax.xml.bind
Teil des JDK, danach wurde es aus dem JDK entfernt und ist nun als Teil der von JEE zu Jakarta EE umbenannten Spezifikation als "Jakarta XML Binding" mit dem Package jakarta.xml.bind
verfügbar. Dazu werden Annotationen an Klassen und Felder generiert:
1 | Der LocalDateAdapter wird bei Verwendung der Java-8-Variante des LocalDate generiert, für die veraltete Joda-Time-Variante muss ein eigener Adapter angelegt werden. |
Um die dabei referenzierten Adapter (die JAXB nutzt, um komplexe Datentypen zu String-Repräsentationen zu mappen) muss ein spezieller JAXB-Context erstellt werden. Dies geschieht über die newJAXBContext
-Methoden an einer zur JAXB-Version passenden JaxbSupport
-Klasse. Diese bietet Faktor-IPS in den Modulen faktorips-runtime-javax-xml
bzw. faktorips-runtime-jakarta-xml
an:
// muss auch Modell-Repositories referenzieren
private IRuntimeRepository repository; (1)
private JAXBContext jaxbContext = JaxbSupport.INSTANCE.newJAXBContext(repository);
private String toXml(Object obj) throws JAXBException {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); (2)
StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
return writer.toString();
}
private Object fromXml(String xml) throws JAXBException {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setAdapter(new
ProductConfigurationXmlAdapter(repository));
return unmarshaller.unmarshal(new StringReader(xml));
}
1 | Das Repository muss die verwendeten Produkte beinhalten aber auch ggf. diesen zu Grunde liegende Modellprojekte referenzieren |
2 | Wenn das XML auch von Menschen, z.B. beim Debugging, gelesen wird ist eine Formatierung sinnvoll. |
Die Module mit JAXB-Support können an Stelle von faktorips-runtime
eingebunden werden:
<dependency>
<groupId>org.faktorips</groupId>
<artifactId>faktorips-runtime-javax-xml</artifactId>
<version>${faktorips.version}</version>
</dependency>
bzw.
<dependency>
<groupId>org.faktorips</groupId>
<artifactId>faktorips-runtime-jakarta-xml</artifactId>
<version>${faktorips.version}</version>
</dependency>
Da JAXB als Teil von Java/Jakarta EE häufig schon als Teil eines Anwendungsservers ausgeliefert wird haben wir uns entschieden, die API nur als "provided" Dependency in den neuen Modulen einzubinden. Für Projekte, die nicht auf einem Java EE Server laufen kann es daher notwendig sein, auch für die API und eine Implementierung eine Projektabhängigkeit anzulegen:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.7</version>
</dependency>
Mit Jakarta EE 10 wird Jakarta XML Binding 4 genutzt:
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>4.0.2</version>
</dependency>
1 JAXB(bis Java (EE) 8) : https://www.oracle.com/technical-resources/articles/javase/jaxb.html, Jakarta EE 9: https://jakarta.ee/specifications/xml-binding/3.0/, ab Jakarta EE 10: https://jakarta.ee/specifications/xml-binding/4.0/