JAXB绑定文件:XmlAdapters和包名

我有这样的绑定文件

            

模式类在“example”(正确)中生成,但是“org.w3._2001.xmlschema”中的XmlAdapters(错误)。 我怎样才能解决这个问题?

我也有这个问题,使用它解决了它。

这里创建了org.w3._2001.xmlschema包,因为XJC必须生成一个扩展javax.xml.bind.annotation.adapters.XmlAdapter的类,该类又调用您的解析/打印静态方法。 出于某种原因,它将它们放入这个包中,而不是更有用的地方。

您还没有说过您使用的JAXB实现,但JAXB RI具有javaType绑定自定义的扩展,它允许您直接指定XmlAdapter的子类,而不是parseMethod / printMethod对。 这消除了生成合成XmlAdapter桥类的需要。 有关如何执行此操作,请参阅RI文档 。

我想EclipseLink / Moxy有类似的东西,但是我不确定Java6附带的XJC是否能够实现它(当它们将它带入JRE时,Sun似乎已经从RI中删除了一半有用的东西) 。

对于Apache CXF用户,最干净的方法是使用wsdl2java提供的-p选项。

-p [wsdl-namespace =] PackageName

指定要用于生成的代码的零个或多个包名称。 (可选)指定包名称映射的WSDL名称空间。

在我们的例子中

-p http://www.w3.org/2001/XMLSchema=org.acme.foo

如果你使用cxf-codegen-plugin,那么只需添加另一对

  org.apache.cxf cxf-codegen-plugin ${cxf.version} [...] -p http://www.w3.org/2001/XMLSchema=org.acme.foo [...]  

不需要指向保留的XSD命名空间的targetNamespace,也不需要catch-all jaxb包绑定。

使用GlobalBinding的更好方法是指定显式适配器,而不是使用此解析/打印对。 例如,而不是以下内容:

  

相反,你应该:

  

请记住为xjc添加名称空间:

 xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jxb:extensionBindingPrefixes="xjc" 

LongAdapter类是这样的:

 public class LongAdapter extends XmlAdapter { public Long unmarshal(String value) { return your_util_class.parseLong(value); } public String marshal(Long value) { return your_util_class.print(value); } } 

这样,由于您明确指定了适配器类,jaxb将不会生成具有默认包名称org.w3._2001.xmlschema的默认适配器。

避免使用默认包名称org.w3._2001.xmlschema非常重要。 举一个例子,如果你有一个项目A和一个项目B,并且它们都有一些模式和绑定。 以旧方式,它们都生成具有完全相同的完全限定名称的适配器,例如org.w3._2001.xmlschema.Adapter1。 但是,这个适配器可能是项目A中的Long和项目B中的Integer。然后,假设你有一个使用A和B的下游项目C.现在问题变得很糟糕。 如果C需要使用Adapter1,则无法预测使用的是来自A for Long或B来自Integer。 然后,您的应用程序C可能会在一段时间内正常工作,但在某些其他情况下可能会以奇怪的方式失败。 如果发生这种情况,类型exception将是:

 org.w3._2001.xmlschema.Adapter1 is not applicable to the field type java.lang.Double... 

当我在我的环境中使用maven-jaxb2-plugin尝试它时,Roy Truelove提到的解决方案似乎无效,即使理论是正确的。

将内置转换器用于常见数据类型。