Jaxb und Interfaces

Status
Nicht offen für weitere Antworten.

Andreas29

Bekanntes Mitglied
Hi,

ich habe mal eine Frage. Folgende Situation:
Ich habe zwei Interfaces:
Java:
public interface Interface1 {
    public Date getDatum();

    public void setDatum(Date date);
}

und

Java:
public interface Interface2 {
    public Date getDatum();

    public void setDatum(Date date);
}

und eine Klasse
Java:
public class Klasse1 implements Interface1, Interface2 {
    private Date datum;

    public Date getDatum() {
        return datum;
    }

    public void setDatum(Date datum) {
        this.datum = datum;
    }
}

Soweit so gut. Kann ich den Kram jetzt via JaxB irgendwie so mappen, dass ich auf den Interfaces festlege, welche Tags erststellt werden sollen? Momentan schaffe ich es nur, dass er mir das Mapping von Interface1 nimmt. Kann es sein, dass das gar nicht geht, weil er zur Laufzeit ja "nur" ein Objekt der konkreten Klasse hat und somit eigentlich nicht entscheiden kann, welches Mapping er nehmen soll? Oder gibt es da irgendwelche Interfaces / Factorys, in dem ich ihm sage: Unter der Bedingung a nimm Interface1 zum Mapping und unter Bedinung b nimm Interface2?

Dank für die Hilfe,
Andreas
 

Andreas29

Bekanntes Mitglied
Hi Noctarius,

erstmal danke für deine Antwort, aber ich befürchte, dass die Adapter nicht das sind, was ich suche. Soweit ich das verstanden habe, erlauben mir die Adapter den Wert, der in das XML geschrieben bzw aus dem XML gelesen wird zu editieren. Das ist aber nicht das, was ich brauche. Ich möchte irgendwie Einfluss auf den Name der generierten XML-Tags haben. Sprich, ich möchte Jaxb irgendwie sagen:
Nimm unterBedingung blah die Konfiguration von Interface1, unter Bedingung blubb aber die Konfiguration (und somit die Namen der zu erzeugenden Elemente) von Interface2.

Grüße,
Andreas
 

Noctarius

Top Contributor
Hm so ganz verstanden was du willst hab ich nicht, sowas da?

Code:
wenn persistieren {
  wenn foo.valueX ist Foo
    nimm spaltenname von IFoo1
  sonst
    nimm spaltenname von IFoo2
}

Wenn ja, was willst du damit versuchen? Hört sich eher nach einem Designfehler an.
 

Andreas29

Bekanntes Mitglied
Hi,

dass das ganze ein etwas schräges Design ist, sehe ich ein. Hintergrund ist folgender:
Es existiert eine sehr große Datenbanktabelle, aus der mittels Hibernate mehrere verschiedene Datentypen gelesen werden. Darauf habe ich keinen Einfluss, das muss ich so hinnehmen. Diese Datentypen sollen nun mittels JAXB nach XML geschrieben werden. Daher kam die Idee auf, für die Tabelle eine große Entity anzulegen, in der für sämtliche Spalten getter / setter existieren, die dann entsprechend auf die Datenbank gemappt werden. Die verschiedenen Datentypen sollen jetzt "nur" noch als Interfaces existieren, mit entsprechenden Zugriffsmethoden für die jeweils typspezifischen Werte. Da das XML-Mapping aber typspezifisch ist, brauchen wir an den Zugriffsmethoden auf den Interfaces ein JAXB mapping. Und momentan versuche ich herauszufinden, ob ich JAXB überhaupot sagen kann:
Mein Entity "Klasse" implementiert das Interface "Interface1". Liebes JAXB, schau mal auf dem Interface nach dem mapping und nutze alle Informationen, die du dort findest (inkl. wenn es dort für ein Feld keinen getter / setter gibt, schreibe es nicht nach XML). Das wäre im Moment erstmal Schritt 1.
Schritt 2 wäre dann:
Meine Entity "Klasse" implementiert die Interfaces "Interface1" und "Interface2". Liebes JAXB, wenn der Wert des Members "markierung" gleich X ist, dann nimm das mapping von "Interface1", wenn der Wert Y ist, nimm das mapping von "Interface2", ansonsten schmeiß eine UnsupportedOperationException().

Ist sowas möglich?

Ich hoffe, mein Ziel ist jetzt deutlicher geworden...

Grüße,
Andreas
 

Noctarius

Top Contributor
Joar aber sowas in der Art funktioniert doch mit den Adaptern. Anstatt AlteKlasse und NeueKlasse aus dem Beispiel nimmst du einmal das Entity von Hibernate und einmal das Interface (je einmal als Eingabewert und einmal als Ausgabewert).

Die jeweiligen Adapterklassen hängst du dann über das Annotation an die Interfaces und musst halt nur entsprechende Methoden haben, welche entsprechend entscheidet als welches Interface das Ganze behandelt wird.
 

Noctarius

Top Contributor
So da mich das jetzt auch interessiert hat habe ich mal eine Minidemonstration gebastelt. Wie du darin siehst geht es auch, aber schön ist dann definitiv was anderes.

Ein Datenobjekt mit 2 Unterdatentypen (JaxB Mapper) wäre da schöner. Ist in dem Datenobjekt ein Property null wird es eh nicht persistiert.
 

Andreas29

Bekanntes Mitglied
Hi,

erstmal danke für deine Mühe, aber entweder verstehe ich dein Beispiel noch nicht oder es nicht nicht das was ich brauche. Mein Code sieht so aus:
Entity:
Java:
package de.andreasgrund.mapping.test.impl;

import javax.xml.bind.annotation.XmlRootElement;

import de.andreasgrund.mapping.test.interface1.Interface1;
import de.andreasgrund.mapping.test.interface2.Interface2;

@XmlRootElement(name = "entity")
public class Entity implements Interface1, Interface2 {

    private String nummer;

    private String datum;

    public String getNummer() {
        return nummer;
    }

    public void setNummer(String nummer) {
        this.nummer = nummer;
    }

    public String getDatum() {
        return datum;
    }

    public void setDatum(String datum) {
        this.datum = datum;
    }

}

Interface1:
Java:
package de.andreasgrund.mapping.test.interface1;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import de.andreasgrund.mapping.test.impl.Interface1Adapter;

@XmlRootElement(name = "interface1")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "kopf", propOrder = { "nummer" })
@XmlJavaTypeAdapter(value = Interface1Adapter.class)
public interface Interface1 {

    @XmlElement(name = "nr")
    public String getNummer();

    public void setNummer(String nummer);
}

Interface2:
Java:
package de.andreasgrund.mapping.test.interface2;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "entityroot2")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "kopf", propOrder = { "gennr", "gendat" })
public interface Interface2 {
    @XmlElement(name = "gennr")
    public String getNummer();

    public void setNummer(String nummer);

    @XmlElement(name = "gendat")
    public String getDatum();

    public void setDatum(String datum);
}
So, das möchte ich jetzt so mappen, dass ich meinetwegen im Adapter sagen kann:
Wenn Bedingung blah, dann schreibe mir ein Mapping laut Interface1, sprich nur ein subtag nummer mit dem root element interface1, ansonsten gehe laut Interface2 vor
 

Noctarius

Top Contributor
Beide Interfaces müssen ein gemeinsames Interface erweitern und dieses basisInterface muss als Implementierung aus dem Adapter geschmissen werden.

Die wichtigen Klassen sind alle im Package jaxb definiert.

Und entsprechend in Adapter ist der Adapter.

Code:
interface IPerson extends IJaxbDelegate
interface IAddress extends IJaxbDelegate

JaxbDelegateImpl implements IJaxbDelegate
PersonImpl extends JaxbDelegateImpl implements IPerson
AddressImpl extends JaxbDelegateImpl implements IAddress

IPersonData extends IPerson, IAddress
PersonDataextends JaxbDelegateImpl implements IPersonData

XmlAdapter von IPersonData nach JaxbDelegateImpl

Da alles von JaxbDelegateImpl abgeleitet ist, kannst du es als Supertype aus dem Adapter rauswerfen und halt die passende Implementierung auswählen (je nach Bedingung PersonImpl oder AddressImpl - welche die Daten persistieren).

Die eigentliche Bedingung was geschrieben wird muss in die 2 Methoden des Adapters.
 
Zuletzt bearbeitet:

Andreas29

Bekanntes Mitglied
Hi,

das klingt alles gut und sinnvoll und funktioniert auch (wie das Beispiel, das du gepostet hast demonstriert), nur leider ist es nicht das, was ich brauche. Ich habe kein AddressImpl und kein PersonImpl. Ich habe nur ein PersonDataImpl und die beiden Interfaces IAddress und IPerson. Und auf den beiden Interfaces möchte ich das mapping für JAXB unterbringen. Und um das ganze noch ein wenig schwerer zu machen: Sowohl IPerson als auch IAddress haben beide eine Methode getId(), die im Falle von IPerson als <id>1234</id> und im Falle von IAddress als <identifier>1234</identifier> geschrieben werden soll...

Grüße,
Andreas
 

Noctarius

Top Contributor
Entweder machst du die 2 Implementierungen einfach oder du nimmst die Lösung die mir heute Nacht eingefallen ist.
Ich habe im Anhang das alte projekt überarbeitet und eine Reihe an "Conditional"-Classes eingefügt welche als Dreh und Angelpunkt den Adapter nutzt.

Java:
public class JaxbConditionalPersonDataAdapter extends XmlAdapter<ConditionalPersonData, IConditionalPersonData> {

	@Override
	public ConditionalPersonData marshal(IConditionalPersonData arg) throws Exception {
		if (arg.getCity() != null) {
			ConditionalPersonData impl = new ConditionalPersonData();
			
			impl.setId(arg.getId());
			impl.setStreet(arg.getStreet());
			impl.setNumber(arg.getNumber());
			impl.setZipCode(arg.getZipCode());
			impl.setCity(arg.getCity());
			
			return impl;
		} else {
			ConditionalPersonData impl = new ConditionalPersonData();
			
			impl.setId(arg.getId());
			impl.setName(arg.getName());
			impl.setSurname(arg.getSurname());
			impl.setBirthday(arg.getBirthday());
			
			return impl;
		}
	}

	@Override
	public IConditionalPersonData unmarshal(ConditionalPersonData arg) throws Exception {		
		return arg;
	}

}

Der komplette Source ist wieder im Anhang zu finden.
 
Zuletzt bearbeitet:

Andreas29

Bekanntes Mitglied
Hi,

ich werde wohl die zwei Implementierungen machen. Dürfte wohl das einfachste vorgehen sein.

Dank dir für deine ausführliche Hilfe und deine Mühe.

Grüße,
Andreas
 

Noctarius

Top Contributor
Wie gesagt Alternative ist eben den Adapter als Conditional Bindeglied nutzen und eine neue Instanz zurückgeben, welche nur die zu persistierenden Daten beinhaltet.

PS: Ich danke, ich hab darauf hin angefangen gerade unser firmeninternes OSGi Exporter Framework anzupassen :D Wieder eine Möglichkeit mehr, die es jetzt geschickt anbindet *hehe*
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
L JAXB und Interfaces XML & JSON 4
S JAXB 2 und Java Annotationen/Interfaces generieren XML & JSON 3
HombreDelMundo JAXB can't handle interfaces XML & JSON 4
turmaline JAXB can't handle interfaces XML & JSON 20
8u3631984 jaxb XML Mapper - Root Element mit Attribut XML & JSON 20
W jaxws jaxb wsdl Java-Klassen generieren und binding.xml verwenden XML & JSON 1
Rakshan Unmarshalling multiple namespaces with jaxb XML & JSON 0
B JAXB und HTML XML & JSON 1
E JAXB und java.nio.file.Path XML & JSON 4
W jaxb-api XML Feld nicht gesendet setzt das Defaultvalue nicht XML & JSON 3
S Muss ich bei JAXB immer noch eine zusaetzliche List-Wrapper Klasse erstellen wenn ich mehrere Objekte serialisieren will..? XML & JSON 1
S JAXB mit mehreren zusammenhängenden .xsd-Files XML & JSON 0
N JAXB: Überflüssiges Wrapper-Tag für Map-Einträge XML & JSON 0
D JAXB mit Map und Color XML & JSON 2
K JAXB-XML unvollständig XML & JSON 1
K JAXB Unmarshelling XML & JSON 1
E JAXB und abstrakte Klasse(n) XML & JSON 0
B JAXB - Unmarshal -> Kinder bekommen und die Kinder von den Kinder XML & JSON 7
B JAXB - Marshal ArrayList XML & JSON 2
B JAXB - java.util.Locale does not have a no-arg default constructor XML & JSON 2
B JAXB-Fehler bei REST-Api XML & JSON 0
M JAXB HashMap Dynamisches Laden XML & JSON 0
M JAXB @XMLID und @XMLIDREF, wie Daten hinzufügen XML & JSON 2
P JAXB-Problem XML & JSON 1
A JAXB: XMLMixed generieren XML & JSON 0
R [JAXB] XmlRootElement und XmlType gemeinsam nutzen XML & JSON 0
I XML to Object - Mapping mit JAXB 1.0 XML & JSON 1
L JAXB - Generischen Wert mit Liste belegen XML & JSON 1
M XML-Datei mit JAXB und 2 Namespaces XML & JSON 0
K JAXB Annotation @XMLRootElement vererben XML & JSON 0
F JAXB Unmarshal - Kein "default Constructor" XML & JSON 2
F.S.WhiTeY JAXB: Schema nicht "erben" XML & JSON 2
B JAXB - manuell Klassen aus xsd XML & JSON 3
S Jaxb Unmarshalling Problem XML & JSON 4
S JAXB - Any Elementliste - wie Werte verändern? XML & JSON 4
R JAXB: A cycle is detected in the object graph. This will cause infinitely deep XML XML & JSON 6
M JAXB versucht abstrakte Klasse zu erzeugen XML & JSON 7
M JAXB: automatisches Groß schreiben Property XML & JSON 9
C Projekt - JAXB, EMF oder doch DOM? XML & JSON 4
C JAXB: XML-Elemente einlesen und als XML-Attribute ausgeben XML & JSON 7
R sax, stax, jdom, jaxb? List von Objekten speichern und laden XML & JSON 6
J JAXB: Mehrmals abspeichern XML & JSON 3
D XML Einlesen mit JaxB XML & JSON 4
W JAXB Binding customization XML & JSON 4
S Problem with JAXB unmarshalling classes that have the same name in @XmlRootElement XML & JSON 2
eykarhorn JAXB namespace attribut aus rootelement entfernen XML & JSON 2
nrg JAXB - nor any of its super class is known to this context XML & JSON 3
S aus XML mit JAXB zu Baumstruktur XML & JSON 3
nrg JAXB generell auf XMLs übertragbar XML & JSON 22
Landei JAXB: Wert von übergeordneten Element XML & JSON 4
B PropertyChangeListener generieren mit JAXB (xjc) XML & JSON 3
G JAXB und verschachtelte Elemente? XML & JSON 6
G JAXB XML-Attribute feststellen XML & JSON 4
S JAXB 2 und JSR 303 XML & JSON 11
M [JAXB] @XmlAnyElement namespace XML & JSON 4
R JAXB Unmarshal XML & JSON 2
J JAXB und ArrayList XML & JSON 4
Landei Jpa2 -> jaxb??? XML & JSON 9
M JAXB - HashMap XML & JSON 1
dzim JAXB-Unmarshalling ignoriert/löscht Einträge aus XML - oder lässt sie verschwinden XML & JSON 3
ruutaiokwu jaxb eclipse plugin... XML & JSON 3
K JAXB: Klassen mit Annotation Lesen/Schreiben XML XML & JSON 3
R JAXB ausgewählte Felder XML & JSON 10
TiME-SPLiNTER JAXB: com.sun.xml.bind.v2.ContextFactory XML & JSON 3
V JAXB und leere Listen XML & JSON 2
L compareto(), equals() in JAXB generierten Dateien XML & JSON 3
D jaxb validierung/verification vor marshalling XML & JSON 3
J JAXB mit GregorianCalendar XML & JSON 4
N Individuelles Wrapper-Element um Collection mit JAXB XML & JSON 6
B JAXB Unmarshalling mehrerer Objekte XML & JSON 2
V JAXB schema 2 java XML & JSON 3
B JPA + JAXB Mapping Problem XML & JSON 2
S Navigieren in unbekannten JAXB-Objecten XML & JSON 2
J JAXB NullPointerException im ContextFinder XML & JSON 6
H JAXB und STAX XML & JSON 2
H JAXB Probleme beim Unmarshalling XML & JSON 3
C Serialisierung mit JAXB XML & JSON 6
K JAXB und Maps -> Marshalling-Problem XML & JSON 6
S JAXB und viele verschachtelte Attribute XML & JSON 1
J JAXB - Map XML & JSON 2
O JAXB generierte Klassen sollen Serializable implementieren XML & JSON 1
aze JaxB: Nullelemente in Array nicht anzeigen XML & JSON 3
sambalmueslie JAXB - Unmarshall ein XML-Document das aus zwei XSD Definitionen besteht XML & JSON 8
S JAXB und abstrakte Klasse(n) XML & JSON 4
P JAXB: Marshalling XML & JSON 7
aze JaxB Elemente in LinkedHashSet werden nicht wiededergegeben XML & JSON 3
M JAXB: Wie folgendes Konstrukt abbilden? XML & JSON 20
B JaxB und XSD :-) XML & JSON 8
G JAXB - Marshaller - kein Rückgabewert XML & JSON 2
N XML will nicht weder JAXB noch XStream XML & JSON 8
F Zugriff auf durch JAXB erzeugte Object-Struktur... XML & JSON 6
C Java-Imports bei Jaxb XML & JSON 8
F Marshaling eines JAXB Objektes worin ein anderes JAXB Objekt eingeschlossen ist XML & JSON 6
K JAXB, Vererbung und Codegeneration XML & JSON 2
M XmlRootElement und JAXB XML & JSON 4
R JAXB: Aus einem Vector oder List XML Datei erstellen XML & JSON 1
G jaxb Vector (oder ähnliches) von Elementen generieren XML & JSON 6
M Jaxb Annotationen, Wert als XML Element XML & JSON 2
J JCheckbox abfragen und serialisieren mit JAXB 2.0 XML & JSON 15
F JAXB erste schritte XML & JSON 6

Ähnliche Java Themen

Neue Themen


Oben