You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用wsdl2java时通过自定义绑定替换XMLGregorianCalendar

问题

目标是用java.time.LocalDate替代XMLGregorianCalendar处理XML的dateTime类型,已在Maven的pom.xml中配置版本4.0.2的cxf-codegen-plugin执行wsdl2java,配置如下:

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-codegen-plugin</artifactId>
  <version>4.0.2</version>
  <executions>
    <execution>
      <id>generate-sources</id>
      <phase>generate-sources</phase>
      <configuration>
        <sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
        <wsdlOptions>
          <wsdlOption>
            <wsdl>/path/to/the.wsdl</wsdl>
            <bindingFiles>
              <bindingFile>/path/to/binding.xml</bindingFile>
            </bindingFiles>      
            <extraargs>
              <extraarg>-verbose</extraarg>
            </extraargs>          
          </wsdlOption>
        </wsdlOptions>
      </configuration>
      <goals>
        <goal>wsdl2java</goal>
      </goals>
    </execution>
  </executions>
</plugin>

绑定文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.1">    
    <jaxb:globalBindings>
      <xjc:javaType name="java.time.LocalDate"
                     xmlType="xs:dateTime"
                     adapter="my.app.LocalDateAdapter" />
    </jaxb:globalBindings>
</jaxb:bindings>

但生成的Java文件仍对dateTime类型使用默认的XMLGregorianCalendar:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SomeType", propOrder = {
    "someDate"
})
public class SomeType {
    @XmlElement(required = true)
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar someDate;
    ...
}

开启-verbose日志后,wsdl2java未提示绑定文件有任何问题,仿佛完全忽略了绑定规则,请问哪里操作错误?

解决方案

以下是几个核心问题点及修正方法:

1. JAXB版本与命名空间不兼容

CXF 4.x默认使用JAXB 3.x(Jakarta EE规范),但你的绑定文件仍用JAXB 2.x的命名空间和版本号,导致规则不生效。
修正:更新绑定文件的命名空间和版本:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               xmlns:xjc="https://jakarta.ee/xml/ns/jaxb/xjc"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               jaxb:version="3.0">    
    <jaxb:globalBindings>
      <xjc:javaType name="java.time.LocalDate"
                     xmlType="xs:dateTime"
                     adapter="my.app.LocalDateAdapter" />
    </jaxb:globalBindings>
</jaxb:bindings>

同时确保项目依赖的JAXB相关包为Jakarta版本(如jakarta.xml.bind:jakarta.xml.bind-api)。

2. 绑定文件路径错误

检查/path/to/binding.xml是否为项目内的有效路径,Maven中建议使用相对路径(如src/main/resources/binding.xml),避免绝对路径导致文件无法被加载。可通过-verbose日志确认是否有绑定文件加载的相关日志,若无则说明路径错误。

3. 适配器类未正确实现

确保my.app.LocalDateAdapter正确实现XmlAdapter,完成LocalDate与XMLGregorianCalendar的双向转换,示例实现:

import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class LocalDateAdapter extends XmlAdapter<XMLGregorianCalendar, LocalDate> {
    @Override
    public LocalDate unmarshal(XMLGregorianCalendar v) throws Exception {
        if (v == null) return null;
        return v.toGregorianCalendar().toZonedDateTime().toLocalDate();
    }

    @Override
    public XMLGregorianCalendar marshal(LocalDate v) throws Exception {
        if (v == null) return null;
        GregorianCalendar gc = GregorianCalendar.from(v.atStartOfDay(ZoneId.systemDefault()));
        return DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
    }
}

4. 启用JAXB扩展参数

在extraargs中添加-xjc-Xdv参数,强制启用JAXB的自定义绑定扩展:

<extraargs>
  <extraarg>-verbose</extraarg>
  <extraarg>-xjc-Xdv</extraarg>
</extraargs>

5. 清理缓存重新生成

执行mvn clean generate-sources,清理之前生成的旧文件,避免缓存导致修改不生效。

内容的提问来源于stack exchange,提问作者hovu96wtko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 21:27:52