2013-02-20 105 views
2

我有一個堆棧跟蹤嘗試使用moxy繼承,有人可以給一些建議。貝婁一些Java代碼的抽象和堆棧錯誤。提前致謝!!!moxy cxf彈簧繼承

Bussines對象

public abstract class ContactInfo { 

} 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="address") 
public class Address extends ContactInfo { 

    private String street; 

    public String getStreet() { 
     return street; 
    } 

    public void setStreet(String street) { 
     this.street = street; 
    } 

} 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="phonenumber") 
public class PhoneNumber extends ContactInfo { 

} 
import javax.xml.bind.annotation.XmlElementRef; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="customer") 
public class Customer { 

    private ContactInfo contactInfo; 

    @XmlElementRef 
    public ContactInfo getContactInfo() { 
     return contactInfo; 
    } 

    public void setContactInfo(ContactInfo contactInfo) { 
     this.contactInfo = contactInfo; 
    } 

} 

CXF Web服務

import javax.ws.rs.Consumes; 

import javax.ws.rs.POST; 

import javax.ws.rs.Path; 

import javax.ws.rs.Produces; 

import javax.ws.rs.core.MediaType; 

import packagename.payment.ContactInfo; 

import packagename.payment.Payment; 

import packagename.payment.PaymentResponse; 


@Path("/payment/") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public interface PaymentServerRest { 

    @POST 
    @Path("aja1/") 
    public PaymentResponse aja1(Customer customer); 


} 

import java.util.ArrayList; 
import java.util.List; 

import javax.ws.rs.Consumes; 
import javax.ws.rs.POST; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 

import packagename.payment.server.PaymentServerRest; 

import packagename.payment.Address; 

import packagename.payment.ContactInfo; 

import packagename.payment.Customer; 

import packagename.payment.PaymentResponse; 

import packagename.payment.PhoneNumber; 


@Path("/payment/") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public class PaymentServerRestImpl implements PaymentServerRest { 

    @Override 
    @POST 
    @Path("aja1/") 
    public PaymentResponse aja1(Customer customer) { 
     if (customer.getContactInfo() instanceof Address) { 
      System.out.println("aja Address"); 
     } else if (customer.getContactInfo() instanceof PhoneNumber) { 
      System.out.println("aja PhoneNumber"); 
     } 
     return null; 
    } 

} 

客戶端web服務

import packagename.payment.server.PaymentServerRest; 
import packagename.payment.Customer; 
import packagename.payment.Payment; 
import packagename.payment.PaymentResponse; 

public class PaymentClientRest { 

    private static PaymentServerRest server = createClientServer(PaymentServerRest.class, "paymentrest/"); 

    public static PaymentResponse aja1(Customer customer) { 
     try { 
      return server.aja1(customer); 
     } catch (Exception e) { 
      return null; 
     } 

    } 


} 

測試用例

import org.junit.Test; 

import packagename.payment.Address; 
import packagename.payment.Customer; 
import packagename.payment.Payment; 

public class PaymentClientRestTest { 



    @Test 
    public void testAja1() { 
     Customer customer = new Customer(); 
     customer.setContactInfo(new Address()); 

     System.out.println(PaymentClientRest.aja1(customer)); 

     customer = new Customer(); 
     customer.setContactInfo(new PhoneNumber()); 

     System.out.println(PaymentClientRest.aja1(customer)); 


    } 


} 

彈簧配置的beans.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://cxf.apache.org/jaxrs 
     http://cxf.apache.org/schemas/jaxrs.xsd 
     http://www.springframework.org/schema/util 
     http://www.springframework.org/schema/util/spring-util.xsd"> 
    <import resource="classpath:META-INF/cxf/cxf.xml" /> 
    <!-- <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" /> --> 
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> 

    <util:map id="jsonNamespaceMap" map-class="java.util.Hashtable"> 
     <entry key="http://localhost:8080/servicepath/paymentrest" value="payments"/> 
     </util:map> 



    <bean id="jsonMoxyProvider" class="org.eclipse.persistence.jaxb.rs.MOXyJsonProvider"> 
     <property name="attributePrefix" value="@" /> 
     <property name="formattedOutput" value="true" /> 
     <property name="includeRoot" value="true" /> 
     <property name="marshalEmptyCollections" value="false" /> 
     <property name="valueWrapper" value="$" /> 
     <!-- property name="namespaceSeparator" value="" /--> <!-- by default is point --> 
     <property name="namespacePrefixMapper" ref="jsonNamespaceMap" /> 
    </bean> 

    <!-- Payment RestFul service --> 
    <jaxrs:server id="paymentrest" address="/paymentrest"> 
     <jaxrs:serviceBeans> 
      <ref bean="paymentServerRest" /> 
     </jaxrs:serviceBeans> 
     <jaxrs:providers> 
      <ref bean="jsonMoxyProvider"/> 
     </jaxrs:providers> 
    </jaxrs:server> 

    <bean id="paymentServerRest" 
     class="packagename.payment.server.impl.PaymentServerRestImpl" /> 



</beans> 

例外

16:29:27.098 [Main Thread] ERROR o.a.cxf.jaxrs.client.AbstractClient - .Problem with writing the request message, class : class packagename.payment.Customer, ContentType : application/json. 
org.apache.cxf.jaxrs.client.ClientWebApplicationException: org.apache.cxf.interceptor.Fault: .Problem with writing the request message, class : class packagename.payment.Customer, ContentType : application/json. 
    at org.apache.cxf.jaxrs.client.AbstractClient.checkClientException(AbstractClient.java:501) 
    at org.apache.cxf.jaxrs.client.AbstractClient.preProcessResult(AbstractClient.java:488) 
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.doChainedInvocation(ClientProxyImpl.java:531) 
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.invoke(ClientProxyImpl.java:205) 
    at $Proxy13.aja1(Unknown Source) 
    packagename.payment.client.PaymentClientRest.aja1(PaymentClientRest.java:61) 
    packagename.payment.client.PaymentClientRestTest.testAja1(PaymentClientRestTest.java:100) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:21) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:232) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:61) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:223) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:684) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
Caused by: org.apache.cxf.interceptor.Fault: .Problem with writing the request message, class : class packagename.payment.Customer, ContentType : application/json. 
    at org.apache.cxf.jaxrs.client.ClientProxyImpl$BodyWriter.handleMessage(ClientProxyImpl.java:649) 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262) 
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.doChainedInvocation(ClientProxyImpl.java:526) 
    ... 27 more 
Caused by: org.apache.cxf.jaxrs.client.ClientWebApplicationException: .Problem with writing the request message, class : class packagename.payment.Customer, ContentType : application/json. 
    at org.apache.cxf.jaxrs.client.AbstractClient.reportMessageHandlerProblem(AbstractClient.java:611) 
    at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(AbstractClient.java:406) 
    at org.apache.cxf.jaxrs.client.ClientProxyImpl$BodyWriter.handleMessage(ClientProxyImpl.java:640) 
    ... 29 more 
**Caused by: javax.ws.rs.WebApplicationException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions 
Invalid @XmlElementRef : Type "class packagename.payment.ContactInfo" or any of its subclasses are not known to this context. 
    this problem is related to the following location: 
     at public packagename.payment.ContactInfo packagename.payment.Customer.getContactInfo() 
     at packagename.payment.Customer** 

    at org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.handleExceptionEnd(AbstractJAXBProvider.java:585) 
    at org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.handleJAXBException(AbstractJAXBProvider.java:597) 
    at org.apache.cxf.jaxrs.provider.json.JSONProvider.writeTo(JSONProvider.java:361) 
    at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(AbstractClient.java:401) 
    ... 30 more 
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions 
Invalid @XmlElementRef : Type "class packagename.payment.ContactInfo" or any of its subclasses are not known to this context. 
    this problem is related to the following location: 
     at public packagename.payment.ContactInfo packagename.payment.Customer.getContactInfo() 
     at packagename.payment.Customer 

    at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:106) 
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:466) 
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:298) 
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:141) 
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1163) 
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:145) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:203) 
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:363) 
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574) 
    at org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.getClassContext(AbstractJAXBProvider.java:425) 
    at org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.getJAXBContext(AbstractJAXBProvider.java:409) 
    at org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.createMarshaller(AbstractJAXBProvider.java:510) 
    at org.apache.cxf.jaxrs.provider.json.JSONProvider.marshal(JSONProvider.java:508) 
    at org.apache.cxf.jaxrs.provider.json.JSONProvider.writeTo(JSONProvider.java:357) 
    ... 31 more 

回答

1

注:我是EclipseLink JAXB (MOXy)領導和JAXB (JSR-222)專家組的成員。

我會幫你解決這個問題。

JSON提供

第一個問題是,它看起來好像MOXyJsonProvider沒有被拾起並CXF被默認爲基於JSON綁定默認的JAXB。這導致JAXB Ri異常被拋出。

產生的原因:javax.ws.rs.WebApplicationException:com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:輸入「類 packagename.payment.ContactInfo:中 IllegalAnnotationExceptions無效@XmlElementRef 1個計數「或其任何子類不是本文已知的 。 這個問題涉及到以下位置:在公共packagename.payment.ContactInfo packagename.payment.Customer.getContactInfo() 在packagename.payment.Customer

at org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.handleExceptionEnd(AbstractJAXBProvider.java:585) 
at org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.handleJAXBException(AbstractJAXBProvider.java:597) 
at org.apache.cxf.jaxrs.provider.json.JSONProvider.writeTo(JSONProvider.java:361) 
at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(AbstractClient.java:401) 
... 30 more 

子類

你需要讓MOXY知道子類。一種方法是通過@XmlSeeAlso註釋。

@XmlSeeAlso({PhoneNumber.class, Address.class}) 
public abstract class ContactInfo { 

} 

UPDATE

我用一個固定的檢查MOXyJsonProvider中的EclipseLink 2.4.2和2.5.0流來解決的問題的RESTEasy運行時。這可能與您使用CXF時遇到的問題相關,也可能不相關。此修復程序將在每晚構建從以下位置開始2013年2月22日,可供選擇:

+1

喜布萊斯,由於通過了答案,我試着用@XmlSeeAlso({PhoneNumber.class, Address.class})並沒有工作,我會再次嘗試使用最新的版本,並在我有我的測試結果時給你一個反饋。謝謝你的時間 – sjdms265 2013-03-05 20:47:33