【问题标题】:XmlJavaTypeAdapter with CXF and JAX-WS带有 CXF 和 JAX-WS 的 XmlJavaTypeAdapter
【发布时间】:2011-09-17 17:01:51
【问题描述】:

我有一个 X 类,它用在使用 Apache CXFJAX-WS 构建的 Web 服务的服务接口中。此类 X 没有默认构造函数,我想避免使用此默认构造函数。我想知道是否可以使用 @XmlJavaTypeAdapter 注释作为解决方案。

ClassXService 中的方法:

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

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

适配器扩展了 XmlAdapter 并正确定义了 marshal 和 unmarshal 方法。

但是,无论是否使用 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 注释我也会得到异常?

【问题讨论】:

    标签: java web-services jaxb jax-ws cxf


    【解决方案1】:

    改成:

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

    适配器需要定义在参数上,而不是方法上。

    【讨论】:

      【解决方案2】:

      像这样:

      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() {}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-30
        • 2014-05-31
        • 2012-07-18
        • 2011-09-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多