2

我有一个堆栈跟踪试图将继承与 moxy 一起使用,有人可以提供一些建议。下面是 Java 代码和堆栈错误的一些摘要。提前致谢!!!

业务对象

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 网络服务

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;
    }

}

客户端网络服务

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));


    }


}

spring 配置 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
4

1 回答 1

1

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。

我会帮助你解决这个问题。

JSON 提供程序

第一个问题是它似乎MOXyJsonProvider没有被选中,并且 CXF 默认为默认的基于 JAXB 的 JSON 绑定。这会导致抛出 JAXB Ri 异常。

引起:javax.ws.rs.WebApplicationException:com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:1 个 IllegalAnnotationExceptions 计数无效 @XmlElementRef:类型“class packagename.payment.ContactInfo”或其任何子类未知在这种情况下。此问题与以下位置有关:在 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

子类

您需要让 MOXy 知道子类。一种方法是通过@XmlSeeAlso注释。

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

}

更新

我在 EclipseLink 2.4.2 和 2.5.0 流中签入了一个修复程序,MOXyJsonProvider以修复在 RESTEasy 中运行时出现的问题。这可能与您在 CXF 中看到的问题有关,也可能无关。从 2013 年 2 月 22 日开始,该修复程序将在夜间版本中提供,地址如下:

于 2013-02-21T11:44:03.060 回答