我的目标是用不同的 Java 类替换
XMLGregorianCalendar
(例如 java.time.LocalDate
)。
我正在运行
wsdl2java
作为 Maven pom.xml
文件的一部分:
<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 文件仍然使用
XMLGregorianCalendar
(这是默认类)作为 dateTime
XML 类型:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SomeType", propOrder = {
"someDate"
})
public class SomeType {
@XmlElement(required = true)
@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar someDate;
...
}
我期望生成的 Java 代码对
java.time.LocalDate
XML 类型使用 XMLGregorianCalendar
(而不是 dateTime
)。
我见过很多不同的绑定文件变体,但无法让其中之一工作。上面提到的一个绑定文件是我想到的最有前途(但显然是错误的)版本。
尽管启用了详细日志记录 (
<extraarg>-verbose</extraarg>
),但没有任何 wsdl2java 日志消息表明绑定文件中存在问题。无论我尝试什么,感觉就像完全忽略了绑定文件。
知道我做错了什么吗?
为了确保生成的 Java 代码对于 dateTime XML 类型使用 java.time.LocalDate 而不是 XMLGregorianCalendar,您需要配置 cxf-codegen-plugin 以在代码生成期间使用 JAXB 绑定文件。目前似乎未拾取绑定文件。您可以在 pom.xml 中修改插件的配置,如下所示:
<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>
<!-- Add the binding file to the configuration -->
<bindingFiles>
<bindingFile>/path/to/binding.xml</bindingFile>
</bindingFiles>
<extraargs>
<extraarg>-verbose</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
<!-- Add this configuration to use Java 8 Date/Time API -->
<defaultOptions>
<java8>true</java8>
</defaultOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<!-- Add this configuration to use Java 8 Date/Time API -->
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
</plugin>
确保将 /path/to/binding.xml 替换为绑定文件的实际路径。
通过此配置,cxf-codegen-plugin 现在应该在代码生成期间使用指定的绑定文件,并且生成的 Java 类将使用 java.time.LocalDate 而不是 XMLGregorianCalendar 作为 dateTime XML 类型。此外,true 选项使插件能够在生成的代码中生成 Java 8 日期/时间 API 类。
请记住在 pom.xml 中包含 javax.xml.bind:jaxb-api 依赖项,以确保正确使用 Java 8 日期/时间 API。
Try using parseMethod of jakarta namespace xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
<jaxb:globalBindings>
<jaxb:javaType name="java.util.Date" xmlType="xs:date" hasNsContext="false"
parseMethod="com.example.sandbox.jaxb.DateAdapter.parseDate"
printMethod="com.example.sandbox.jaxb.DateAdapter.printDate"/>
</jaxb:globalBindings>
import java.util.GregorianCalendar;
import javax.xml.bind.DatatypeConverter;
public class DateAdapter {
public static Date parseDate(String s) {
return DatatypeConverter.parseDate(s).getTime();
}
public static String printDate(Date dt) {
Calendar cal = new GregorianCalendar();
cal.setTime(dt);
return DatatypeConverter.printDate(cal);
}
}
我找到了一个可行的解决方案。我花了一段时间。
绑定文件如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings version="3.0"
xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxb:globalBindings>
<xjc:javaType name="java.time.LocalDate"
xmlType="xs:dateTime"
adapter="my.app.LocalDateAdapter"/>
</jaxb:globalBindings>
</jaxb:bindings>
与你的文件只有一行的区别:
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
只是另一个命名空间。
为了确认这一点,我在我的 github 上发布了一个示例。如果不起作用请告诉我。