2014-03-04 52 views
1

我在Java中使用的接口的實現。 對於例如:可以有很多PaymentTypes,如信用卡,手機等 我想提出一個REST API包含一個接口 - 我怎麼在JAXB映射此,目前它給了我JAXBException發生:IllegalAnnotationExceptions的2個字。REST API接口與 - JAXB

目前我使用Apache的CXF和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); 
    } 
} 

我應該如何我應該用完全不同的方法來映射這還是?

修改: 對於POST方法,我收到付款。付款可能包含任何對象CreditCard,錢包等。我應該提供哪些註釋,以便正確解密。 目前它引發JAXB異常。你已經有了

回答

2

完整的錯誤信息是:

Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions PaymentType is an interface, and JAXB can't handle interfaces.

您需要使用concreate類的元素或type屬性@XmlElement標註的點吧:

@XmlElement(type = CreditCardDetails.class) 
private PaymentType paymentType; 

如果您有使用PaymentType接口,那麼您可以使用以下解決方案的更多類:

@XmlAnyElement 
@XmlElementRefs({ 
    @XmlElementRef(type=CreditCardDetails.class), 
    @XmlElementRef(type=Wallet.class) 
}) 
PaymentType paymentType; 

@XmlElementRefs的列表可以有任意數量的元素,但所有可能性必須列出。 CreditCardDetailsWallet必須@XmlRootElement進行註釋。

您可以跳過@XmlElementRefs註釋:

@XmlAnyElement(lax=true) 
PaymentType paymentType; 

,但在這種情況下,要確保你有在JAXB上下文中任何所需的類,如果你不使用註冊表與PaymentType場@XmlSeeAlso註解類({ CreditCardDetails.class,Wallet.class})。

+0

你的解決方案的工作,但效果不理想。我正在使用一個界面,因爲我可能會在運行時獲得CreditCard,Mobile或Wallet。 如果我想預先聲明我正在使用CreditCard,那麼我不會在第一時間使用界面。 – user1552879

+2

現在查看答案。這是你需要的嗎? – swist

+1

在'@ XmlAnyElement'上增加了'lax = true',這樣它就會映射到一個對象,而不僅僅是dom。 –