使用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

