XmlJavaTypeAdapter с CXF и JAX-WS - PullRequest
       49

XmlJavaTypeAdapter с CXF и JAX-WS

3 голосов
/ 17 сентября 2011

У меня есть класс X, который используется в интерфейсе службы веб-службы, построенной с Apache CXF и JAX-WS .Этот класс X не имеет конструктора по умолчанию, и я хотел бы избежать этого конструктора по умолчанию.Мне было интересно, могу ли я использовать аннотацию @XmlJavaTypeAdapter в качестве решения.

Методы из ClassXService:

@WebMethod
@XmlJavaTypeAdapter(ClassXAdapter.class)
public void myMethod(ClassX arg0);

@WebMethod
@XmlJavaTypeAdapter(ClassXAdapter.class)
public ClassX myMethod2();

Адаптер расширяет XmlAdapter и правильно определяет методы маршала и демаршала.

Однако с использованием или без использования аннотации XmlJavaTypeAdapter,Я всегда получаю одну и ту же ошибку:

Exception in thread "main" org.apache.cxf.service.factory.ServiceConstructionException
    at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:292)
    at org.apache.cxf.service.factory.AbstractServiceFactoryBean.initializeDataBindings(AbstractServiceFactoryBean.java:86)
    at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:438)
    at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:682)
    at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:501)
    at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:241)
    at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:202)
    at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:101)
    at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:157)
    at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:202)
    at my.package.Main.main(Main.java:35)    
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
    my.package.ClassX does not have a no-arg default constructor.
        this problem is related to the following location:
            at my.package.ClassX
            at private my.package.ClassX my.package.jaxws_asm.MyMethod.arg0
            at my.package.jaxws_asm.MyMethod2
at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1140)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:222)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:383)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:594)
at org.apache.cxf.jaxb.JAXBContextCache.createContext(JAXBContextCache.java:258)
at org.apache.cxf.jaxb.JAXBContextCache.getCachedContextAndSchemas(JAXBContextCache.java:167)
at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:418)
at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:290)
... 10 more

Разве невозможно использовать адаптер, чтобы избежать предоставления конструктора по умолчанию без аргументов?Если да, есть ли у кого-то идея, почему я получаю исключение, даже если используется аннотация XmlJavaTypeAdapter?

Ответы [ 3 ]

4 голосов
/ 18 сентября 2011

Измените его на:


   @WebMethod
   public void myMethod(@XmlJavaTypeAdapter(ClassXAdapter.class)   ClassX arg0);

   @WebMethod
   @XmlJavaTypeAdapter(ClassXAdapter.class)
   public ClassX myMethod2();

Адаптер должен быть определен в параметре, а не в методе.

3 голосов
/ 17 сентября 2011

Проверьте эту ссылку: http://weblogs.java.net/blog/kohsuke/archive/2005/09/using_jaxb_20s.html

этот парень помог мне с множеством проблем с jaxb.

0 голосов
/ 17 сентября 2011

Как это:

public static void main(String[] args) throws Exception {
    JAXBContext context = JAXBContext.newInstance(Foo.class);
    StringWriter stringWriter = new StringWriter();
    context.createMarshaller().marshal(new Foo(new Bar(10)), stringWriter);
    System.out.println(stringWriter);
    Object o = context.createUnmarshaller().unmarshal(new StringReader(stringWriter.toString()));
    System.out.println(o);
}

@XmlRootElement
static class Foo {
    private Bar bar;
    Foo() {}
    Foo(Bar bar) { this.bar = bar; }
    @XmlJavaTypeAdapter(BarAdapter.class)
    public Bar getBar() { return bar; }
    public void setBar(Bar bar) { this.bar = bar; }
    public String toString() { return "Foo{bar=" + bar + '}'; }
}

static class Bar {
    private int x;
    Bar(int x) { this.x = x; }
    public int getX() { return x; }
    public void setX(int x) { this.x = x; }
    public String toString() { return "Bar{x=" + x + '}'; }
}

static class JaxbFriendlyBar {
    private int x;
    JaxbFriendlyBar() {}
    public int getX() { return x; }
    public void setX(int x) { this.x = x; }
}

static class BarAdapter extends XmlAdapter<JaxbFriendlyBar, Bar> {
    @Override
    public JaxbFriendlyBar marshal(Bar bar) throws Exception {
        JaxbFriendlyBar result = new JaxbFriendlyBar();
        result.setX(bar.getX());
        return result;
    }

    @Override
    public Bar unmarshal(JaxbFriendlyBar jaxbFriendlyBar) throws Exception {
        return new Bar(jaxbFriendlyBar.getX());
    }
}

Или просто добавьте конструктор по умолчанию без аргументов:

Bar() {}
...