NickD
NickD

Reputation: 11

JAXB: How do I marshal using field name when the return type is an interface?

If I have a class (A) that contains several properties of the same type (interface B).

I've used the suggestion in http://jaxb.java.net/guide/Mapping_interfaces.html to use a combination of @XmlRootElement and @XmlAnyElement to get around the interface problem:

public interface B {...}

public class A {
...
  @XmlAnyElement
  public B getFirstB(){...}
  @XmlAnyElement
  public B getSecondB(){...}
}

// some concrete implementations of B
@XmlRootElement
public class BImpl implements B {...}

@XmlRootElement
public class AnotherBImpl implements B {...}

I get the following:

<a>
    <bImpl/>
    <anotherBImpl/>
</a>

But I want to distinguish between the properties. How do I get:

<a>
    <firstB>
        <bImpl/>
    </firstB>
    <secondB>
        <anotherBImpl/>
    </secondB>
</a>

As the properties are not collections, I can't use @XmlElementWrapper.

I don't really want to change the code if avoidable.

Any thoughts appreciated. Marshalling in JAXB seems to be very tricky.

Upvotes: 1

Views: 502

Answers (3)

alexsvecencu
alexsvecencu

Reputation: 303

Replace @XmlAnyElement with @XmlElement(type = Object.class). This will distinguish individual fields.

More details on this solution in my answer to a related question.

Upvotes: 1

dma_k
dma_k

Reputation: 10639

I think, no magic can happen in your case. Either use a simple wrapper class (for classic JAXB) or use @XmlPath (for MOXy) (acknowledgements to Blaise Doughan).

Upvotes: 0

Alex Calugarescu
Alex Calugarescu

Reputation: 848

You cannot marshal interfaces in JAXB. How would the unmarshaller know how to instantiate your interface? Check this out, it has a really nice explanation.

Upvotes: 0

Related Questions