使用 WSDL 到 Java (wsdl2java) 时通过自定义绑定替换 XMLGregorianCalendar

问题描述 投票:0回答:3

我的目标是用不同的 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 日志消息表明绑定文件中存在问题。无论我尝试什么,感觉就像完全忽略了绑定文件。

知道我做错了什么吗?

soap binding jaxb wsdl2java
3个回答
0
投票

为了确保生成的 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。


0
投票
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);
      } 
 }

0
投票

我找到了一个可行的解决方案。我花了一段时间。

绑定文件如下所示:

<?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 上发布了一个示例。如果不起作用请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.