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

huangapple go评论88阅读模式
英文:

Replace XMLGregorianCalendar via custom binding when using WSDL to Java (wsdl2java)

问题

我的目标是通过不同的Java类(例如java.time.LocalDate)替换XMLGregorianCalendar

我在Maven的pom.xml文件中运行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文件仍然使用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(而不是XMLGregorianCalendar)作为dateTime XML类型。

我已经看到了许多不同版本的绑定文件,但无法使其中任何一个工作。上面提到的绑定文件是我想出的最有希望的版本(但显然是错误的)。

尽管启用了详细日志记录(<extraarg>-verbose</extraarg>),但wsdl2java的日志消息中没有指示绑定文件中的问题。无论我尝试什么,似乎完全忽略了绑定文件。

关于我做错了什么,有什么想法吗?

英文:

My goal is to replace XMLGregorianCalendar by a different Java class (e.g. java.time.LocalDate).

I'm running wsdl2java as part of a maven pom.xml file:

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

The binding file looks as follows:

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

However, the generated Java file still uses XMLGregorianCalendar (which is the default class) for dateTime XML types:

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

I was expecting the generated Java code to use java.time.LocalDate (instead of XMLGregorianCalendar) for dateTime XML types.

I have seen so many different variations of the binding file but could not get one of them to work. The one binding file mentioned above is the most promising (but obviously wrong) version I came up with.

Although verbose logging is enabled (&lt;extraarg&gt;-verbose&lt;/extraarg&gt;), none of the wsdl2java log messages indicate an issue in the binding file. Whatever I try, it feels like it is completely ignoring the binding file.

Any idea about what I'm doing wrong?

答案1

得分: 1

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

绑定文件看起来像这样:

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

英文:

I found a working solution. It took me a while.

The bindings file looks like this:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;jaxb:bindings version=&quot;3.0&quot;
               xmlns:jaxb=&quot;https://jakarta.ee/xml/ns/jaxb&quot;
               xmlns:xjc=&quot;http://java.sun.com/xml/ns/jaxb/xjc&quot;
               xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;

    &lt;jaxb:globalBindings&gt;
        &lt;xjc:javaType name=&quot;java.time.LocalDate&quot;
                      xmlType=&quot;xs:dateTime&quot;
                      adapter=&quot;my.app.LocalDateAdapter&quot;/&gt;
    &lt;/jaxb:globalBindings&gt;
&lt;/jaxb:bindings&gt;

The difference with your file is only one line:

  • yours: xmlns:jaxb=&quot;http://java.sun.com/xml/ns/jaxb&quot;
  • mine: xmlns:jaxb=&quot;https://jakarta.ee/xml/ns/jaxb&quot;

Just another namespace.

To confirm this, I posted an example on my github. Let me know if it doesn't work.

答案2

得分: 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>
            <!-- 将绑定文件添加到配置中 -->
            <bindingFiles>
              <bindingFile>/path/to/binding.xml</bindingFile>
            </bindingFiles>
            <extraargs>
              <extraarg>-verbose</extraarg>
            </extraargs>          
          </wsdlOption>
        </wsdlOptions>
        <!-- 添加此配置以使用Java 8日期/时间API -->
        <defaultOptions>
          <java8>true</java8>
        </defaultOptions>
      </configuration>
      <goals>
        <goal>wsdl2java</goal>
      </goals>
    </execution>
  </executions>
  <!-- 添加此配置以使用Java 8日期/时间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类将在处理dateTime XML类型时使用java.time.LocalDate而不是XMLGregorianCalendar。另外,<java8>true</java8>选项使插件能够在生成的代码中生成Java 8日期/时间API类。

请记得在您的pom.xml中添加<javax.xml.bind:jaxb-api>依赖项,以确保正确使用Java 8日期/时间API。

英文:

To make sure the generated Java code uses java.time.LocalDate instead of XMLGregorianCalendar for dateTime XML types, you need to configure the cxf-codegen-plugin to use the JAXB binding file during code generation. It seems like the binding file is not being picked up currently. You can modify the configuration of the plugin in your pom.xml as follows:

&lt;plugin&gt;
  &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
  &lt;artifactId&gt;cxf-codegen-plugin&lt;/artifactId&gt;
  &lt;version&gt;4.0.2&lt;/version&gt;
  &lt;executions&gt;
    &lt;execution&gt;
      &lt;id&gt;generate-sources&lt;/id&gt;
      &lt;phase&gt;generate-sources&lt;/phase&gt;
      &lt;configuration&gt;
        &lt;sourceRoot&gt;${project.build.directory}/generated-sources/cxf&lt;/sourceRoot&gt;
        &lt;wsdlOptions&gt;
          &lt;wsdlOption&gt;
            &lt;wsdl&gt;/path/to/the.wsdl&lt;/wsdl&gt;
            &lt;!-- Add the binding file to the configuration --&gt;
            &lt;bindingFiles&gt;
              &lt;bindingFile&gt;/path/to/binding.xml&lt;/bindingFile&gt;
            &lt;/bindingFiles&gt;
            &lt;extraargs&gt;
              &lt;extraarg&gt;-verbose&lt;/extraarg&gt;
            &lt;/extraargs&gt;          
          &lt;/wsdlOption&gt;
        &lt;/wsdlOptions&gt;
        &lt;!-- Add this configuration to use Java 8 Date/Time API --&gt;
        &lt;defaultOptions&gt;
          &lt;java8&gt;true&lt;/java8&gt;
        &lt;/defaultOptions&gt;
      &lt;/configuration&gt;
      &lt;goals&gt;
        &lt;goal&gt;wsdl2java&lt;/goal&gt;
      &lt;/goals&gt;
    &lt;/execution&gt;
  &lt;/executions&gt;
  &lt;!-- Add this configuration to use Java 8 Date/Time API --&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;javax.xml.bind&lt;/groupId&gt;
      &lt;artifactId&gt;jaxb-api&lt;/artifactId&gt;
      &lt;version&gt;2.3.1&lt;/version&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/plugin&gt;

Make sure to replace /path/to/binding.xml with the actual path to your binding file.

With this configuration, the cxf-codegen-plugin should now use the specified binding file during code generation, and the generated Java classes will use java.time.LocalDate instead of XMLGregorianCalendar for dateTime XML types. Additionally, the <java8>true</java8> option enables the plugin to generate Java 8 Date/Time API classes in the generated code.

Remember to have the <javax.xml.bind:jaxb-api> dependency in your pom.xml to ensure that the Java 8 Date/Time API is used properly.

答案3

得分: 0

尝试使用 jakarta 命名空间 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);
}

}

英文:
Try using parseMethod of jakarta namespace xmlns:jaxb=&quot;https://jakarta.ee/xml/ns/jaxb&quot;

&lt;jaxb:globalBindings&gt;
 &lt;jaxb:javaType name=&quot;java.util.Date&quot;  xmlType=&quot;xs:date&quot; hasNsContext=&quot;false&quot;
        parseMethod=&quot;com.example.sandbox.jaxb.DateAdapter.parseDate&quot;
        printMethod=&quot;com.example.sandbox.jaxb.DateAdapter.printDate&quot;/&gt;
&lt;/jaxb:globalBindings&gt;

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);
      } 
 }

huangapple
  • 本文由 发表于 2023年7月28日 04:38:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76783271.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定