我有一个类X,它用于使用 Apache CXF 和 JAX-WS 构建的Web服务的Service接口。这个类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注释,有人也知道为什么我会得到异常吗?
答案 0 :(得分:4)
将其更改为:
@WebMethod
public void myMethod(@XmlJavaTypeAdapter(ClassXAdapter.class) ClassX arg0);
@WebMethod
@XmlJavaTypeAdapter(ClassXAdapter.class)
public ClassX myMethod2();
需要在参数上定义适配器,而不是方法。
答案 1 :(得分:3)
查看此链接: http://weblogs.java.net/blog/kohsuke/archive/2005/09/using_jaxb_20s.html
这家伙帮我解决了很多jaxb问题。
答案 2 :(得分:0)
像这样:
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());
}
}
或者只是添加一个no-arg默认构造函数:
Bar() {}