0

My application receives, from another application, xml of the form:

<targetedMessage>
    <sender>the sender</sender>
    <payload class="other.app.classpath.Foo">
        <id>1</id>
    </payload>
</targetedMessage>

where Foo is any one of several classes which exist in both my module and the other application, and implements a common interface:

@XmlAccessorType(value = XmlAccessType.FIELD)
@XmlRootElement
public class Foo implements MyInterface {
    private long id;
    \\ getters and setters
}

and the TargetedMessage class is:

@XmlAccessorType(value = XmlAccessType.FIELD)
@XmlRootElement
public class TargetedMessage {
    private String sender;
    private MyInterface payload;
    \\ getters and setters
}

I have an enum which maps the other apps class-paths to their classes in my module:

public enum MyClasses {
    FOO(Foo.class, "other.app.classpath.Foo"),
    BAR(Bar.class, "other.app.classpath.Bar"),
    \\ ...
}

Using JAXB, is it possible to unmarshal the xml so that the payload is of the correct type (in the above case, the payload class would be Foo).

Chris
  • 409
  • 3
  • 17
  • It's possible, but you'll need to define a class that can contain the content of any of your MyInterface implementations. I don't feel like writing an answer, so see https://dzone.com/articles/jaxb-and-inhertiance-using – kumesana Jun 27 '18 at 13:51

1 Answers1

0

I don't know about JAXB but SimpleXml can do it:

@XmlName("targetedMessage")
public class TargetedMessage {
    String sender;
    @XmlAbstactClass(attribute="class", types={
        @TypeMap(name="other.app.classpath.Foo", type=Foo.class),
        @TypeMap(name="other.app.classpath.Bar", type=Bar.class)
    })
    Payload payload;
}
interface Payload {}
public class Foo implements Payload {
    Integer id;
}
public class Bar implements Payload {
    String name;
}

final String data = ...

final SimpleXml simple = new SimpleXml();
final TargetedMessage message = simple.fromXml(data, TargetedMessage.class);
System.out.println(message.payload.getClass().getSimpleName());
System.out.println(((Foo)message.payload).id);

Will output:

Foo
1

From maven central:

<dependency>
    <groupId>com.github.codemonstur</groupId>
    <artifactId>simplexml</artifactId>
    <version>1.5.0</version>
</dependency>
jurgen
  • 325
  • 1
  • 11