Reputation: 99
I am using an implementation of an interface in Java. For eg: There can be many PaymentTypes like Credit Card, Mobile etc. I am making a REST API which contains an interface- how do I map this in JAXB, currently it gives me JAXBException occurred : 2 counts of IllegalAnnotationExceptions.
Currently I am using Apache-CXF and JAXb
@XmlRootElement
public class Payment {
@XmlElement
private PaymentType paymentType;
@XmlElement
private long price;
public Payment() {
}
public Payment(final PaymentType paymentType, final long price) {
super();
this.paymentType = paymentType;
this.price = price;
}
}
@Path("/trial")
public class TrialService {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Payment> getPayments() {
final List<Payment> payments = new LinkedList<Payment>();
final CreditCardDetails creditCard = new CreditCardDetails(
"8767798778", "123", 12, 2016);
final Payment payment = new Payment(creditCard, 10);
payments.add(payment);
return payments;
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public PaymentDetails startPayment(final PaymentDetails paymentDetails) {
return paymentDetails;
}
}
public class CreditCardDetails implements PaymentType {
@XmlElement
private String creditCardNumber;
@XmlElement
private String cvv;
@XmlElement
private int expirationMonth;
@XmlElement
private int expirationYear;
public CreditCardDetails() {
}
@SuppressWarnings("javadoc")
public CreditCardDetails(
// final BillingAddress billingAddress,
final String creditCardNumber, final String cvv,
final int expirationMonth, final int expirationYear) {
super();
this.creditCardNumber = creditCardNumber;
this.cvv = cvv;
setExpirationMonth(expirationMonth);
setExpirationYear(expirationYear);
}
}
How should I be mapping this or should I be using an entirely different approach?
Edits: For the POST method I am receiving a payment. Payment could contain any object CreditCard, Wallet etc. What annotation should I provide so that it is desirialized correctly. Currently it throws a JAXB exception.
Upvotes: 1
Views: 566
Reputation: 1171
The full error message which you've got is:
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions PaymentType is an interface, and JAXB can't handle interfaces.
You need to use concreate class for your elements or point it in type
attribute of @XmlElement
annotation:
@XmlElement(type = CreditCardDetails.class)
private PaymentType paymentType;
If you have more classes that uses PaymentType
interface then you may use the following solution:
@XmlAnyElement
@XmlElementRefs({
@XmlElementRef(type=CreditCardDetails.class),
@XmlElementRef(type=Wallet.class)
})
PaymentType paymentType;
The list of @XmlElementRefs
can have any number of elements but all possibilities must be listed. CreditCardDetails
and Wallet
must be annotated with @XmlRootElement
.
You can skip @XmlElementRefs annotation:
@XmlAnyElement(lax=true)
PaymentType paymentType;
but in that case make sure you have any required class in JAXB context, if you do not use registry annotate your class with PaymentType
field with @XmlSeeAlso({CreditCardDetails.class, Wallet.class}).
Upvotes: 2