JAXB、自定义绑定、适配器 1.class 和 Joda-time

2022-09-05 00:13:39

我对 JAXB 为 XML 模式生成绑定类的方式有问题(为了精确起见,我无法修改)。我想将 xsd:date 类型映射到 Joda-time LocalDate 对象,并且在这里、这里这里阅读,我创建了以下 DateAdapter 类:

public class DateAdapter extends XmlAdapter<String,LocalDate> {
    private static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");

    public LocalDate unmarshal(String v) throws Exception {
        return fmt.parseLocalDate(v);
    }

    public String marshal(LocalDate v) throws Exception {
        return v.toString("yyyyMMdd");
    }
}

我已将以下内容添加到我的全局绑定文件中:

  <jaxb:globalBindings>
        <jaxb:javaType name="org.joda.time.LocalDate" xmlType="xs:date"
            parseMethod="my.classes.adapters.DateAdapter.unmarshal"
            printMethod="my.classes.adapters.DateAdapter.marshal" />
    </jaxb:globalBindings>

问题是,当我尝试编译我的项目时,它失败了,并出现以下错误:

[ERROR] \My\Path\MyProject\target\generated-sources\xjc\my\classes\generated\Adapter1.java:[20,59] non-static method unmarshal(java.lang.String) cannot be referenced from a static context
[ERROR] \My\Path\MyProject\target\generated-sources\xjc\my\classes\generated\Adapter1.java:[24,59] non-static method marshal(org.joda.time.LocalDate) cannot be referenced from a static context

...这就是事情变得奇怪的地方。JAXB 生成一个包含以下内容的类 Adapter1:

public class Adapter1
    extends XmlAdapter<String, LocalDate>
{


    public LocalDate unmarshal(String value) {
        return (my.classes.adapters.DateAdapter.unmarshal(value));
    }

    public String marshal(LocalDate value) {
        return (my.classes.adapters.DateAdapter.marshal(value));
    }

}

....这是编译错误的根源。

现在,我的问题是:

  • 由于我的适配器正在覆盖XmlAdapter,我无法使这些方法保持静态。...我该如何避免这种情况?
  • 我可以完全避免适配器1.class的生成吗?也许使用包级注释XmlJavaTypeAdapters,如果是这样,我该怎么做?(JAXB已经生成了一个软件包信息.java它自己的....)

希望我把我的情况说清楚。
谢谢


答案 1

我处于WSDL的第一个上下文中:根本没有java,只是从提供的WSDL生成一个CXF客户端。

我被困在丑陋的地方很长一段时间,但我在那里找到了解决方案。Adapter1.java

您将使用自定义 XMLAdapter,如前所述。

此问题的关键是将扩展名添加到全局绑定文件:xjc

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
 jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.1">
    <jaxb:globalBindings>
       <xjc:javaType adapter="com.xxx.tools.xjc.DateAdapter" 
        name="java.util.Date" xmlType="xs:dateTime" />
    </jaxb:globalBindings>
</jaxb:bindings>

xjc 扩展允许使用该 accept 适配器参数。无需更多的静态方法!xjc:javaType

请注意,这似乎仅适用于 jaxb 2.1+。


答案 2

您不需要扩展 。XmlAdapter

只需在POJO上创建静态方法,它就会起作用。

例:

 public class DateAdapter {
    private static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");

    public static LocalDate unmarshal(String v) throws Exception {
        return fmt.parseLocalDate(v);
    }

    public static String marshal(LocalDate v) throws Exception {
        return v.toString("yyyyMMdd");
    }
 }