将 wsdl 生成的 XmlGregorianCalendar 类型的日期替换为 java.util.Date?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40549526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 05:18:43  来源:igfitidea点击:

Replacing date of type XmlGregorianCalendar generated by wsdl to java.util.Date?

javadatewsdl

提问by shuchi

I am working on an application in which we give call to Third Party SAP system using files generated through wsdl using Spring webservices.

我正在开发一个应用程序,在该应用程序中,我们使用 Spring 网络服务通过 wsdl 生成的文件调用第三方 SAP 系统。

One of the file generated using wsdl through ws import have Date attribute of type "XMLGregorianCalendar" and in response we are getting null value for corresponding field .

通过 ws import 使用 wsdl 生成的文件之一具有“XMLGregorianCalendar”类型的日期属性,作为响应,我们为相应的字段获取空值。

I want to convert date from XmlGregorianCalendar to java.util.Date.

我想将日期从 XmlGregorianCalendar 转换为 java.util.Date。

Have referred : how replace XmlGregorianCalendar by Date?but not able to provide appropriate xjb bindings through wsdl.

已经提到:如何用日期替换 XmlGregorianCalendar?但无法通过 wsdl 提供适当的 xjb 绑定。

If anyone can suggest the conversion of Dates generated by wsdl ,it would be of great help..... Thanks In Advance ! Shuchi

如果有人可以建议转换 wsdl 生成的日期,那将有很大帮助..... 提前致谢!舒驰

回答by Vadim

WSDL has no deal with xjb. xjb is for xjc compiler passed as -b parameter. i.e.

WSDL 与 xjb 无关。xjb 用于作为 -b 参数传递的 xjc 编译器。IE

xjc -b <file>

documentation: Customizing JAXB Binding

文档:自定义 JAXB 绑定

if you use Maven plugins to generate your JAXB Java classes any of them have Binding configuration i.e.

如果您使用 Maven 插件来生成您的 JAXB Java 类,其中任何一个都具有绑定配置,即

<groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <configuration>
                    <defaultOptions>
                        <bindingFiles>
                            <bindingFile>${project.interfaces.basedir}Configuration/Bindings/common-binding.xjb</bindingFile>
                        </bindingFiles>

or

或者

<plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <configuration>
                <schemaDirectory>${basedir}/src/main/resources/XMLSchema</schemaDirectory>
                <bindingDirectory>${basedir}/src/main/resources/Bindings</bindingDirectory>
            </configuration>

and so on...

等等...

xjb for it is very simple:

xjb 因为它很简单:

<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc">
<jaxb:globalBindings>
    <jaxb:serializable uid="1" />
    <jaxb:javaType name="java.util.Calendar" xmlType="xsd:dateTime"
        parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime"
        printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />
    <jaxb:javaType name="java.util.Calendar" xmlType="xsd:date"
        parseMethod="javax.xml.bind.DatatypeConverter.parseDate" printMethod="javax.xml.bind.DatatypeConverter.printDate" />
    <jaxb:javaType name="java.util.Calendar" xmlType="xsd:time"
        parseMethod="javax.xml.bind.DatatypeConverter.parseTime" printMethod="javax.xml.bind.DatatypeConverter.printTime" />            
</jaxb:globalBindings>

as you can see it defines conversions from xsd:dateTime, xsd:date and xsd:time types to java.util.Calendar.

如您所见,它定义了从 xsd:dateTime、xsd:date 和 xsd:time 类型到 java.util.Calendar 的转换。

I do not recommend to use java.util.Date. There are many troubles with Date handling (especially with different timeZones). It is better to use java.util.Calendar. Calendar is much easier to handle and default converter implementation is there in JDK:

我不推荐使用 java.util.Date。日期处理有很多问题(尤其是不同的时区)。最好使用 java.util.Calendar。日历更容易处理,JDK 中有默认的转换器实现:

javax.xml.bind.DatatypeConverter

But, if you still want to use java.Util.Date you need to have your own small converter with two static methods "parse" and "print" and then set it in xjb. i.e.

但是,如果您仍然想使用 java.Util.Date,您需要拥有自己的小型转换器,其中包含两个静态方法“解析”和“打印”,然后将其设置在 xjb 中。IE

public class MyDateConverter {
    public static java.util.Date parse(String xmlDateTime) {
        return javax.xml.bind.DatatypeConverter.parseDateTime(xmlDateTime).getTime();
    }

    public static String print(Date javaDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(javaDate.getTime());
        return javax.xml.bind.DatatypeConverter.printDateTime(calendar);
    }
}

your conversions in xjb will look like:

您在 xjb 中的转换将如下所示:

<jaxb:javaType name="java.util.Date" xmlType="xsd:dateTime"
    parseMethod="MyDatatypeConverter.parse"
    printMethod="MyDatatypeConverter.print" />

回答by sahoora

You have to create a custom Data type adaptor and add in binding file.

您必须创建自定义数据类型适配器并添加绑定文件。

 <jaxb:globalBindings>
    <xjc:serializable uid="-6026937020915831338" />
    <xjc:javaType name="java.util.Date" xmlType="xs:date" 
          adapter="com.test.util.jaxb.DateDataTypeAdapter" />
  </jaxb:globalBindings>
</jaxb:bindings>

Class DateDataTypeAdapter

类 DateDataTypeAdapter

package com.test.util.jaxb;

import java.util.Calendar;
import java.util.Date;
import javax.xml.bind.DatatypeConverter;

public final class DataTypeAdapter {
    private DataTypeAdapter() { }

    public static Date parseDate(String s) {
        if (s == null) {
            return null;
        }

        return DatatypeConverter.parseDate(s).getTime();
    }

    public static String printDate(Date dt) {
        if (dt == null) {
            return null;
        }

        Calendar c = Calendar.getInstance();
        c.setTime(dt);

        return DatatypeConverter.printDate(c);
    }

    public static Date parseDateTime(String s) {
        if (s == null) {
            return null;
        }

        return DatatypeConverter.parseDateTime(s).getTime();
    }

    public static String printDateTime(Date dt) {
        if (dt == null) {
            return null;
        }

        Calendar c = Calendar.getInstance();
        c.setTime(dt);

        return DatatypeConverter.printDateTime(c);
    }
}

回答by Manuel Spigolon

I have change the bean's java type from XMLGregorianCalendaradding the configuration for jaxb directly on the xsd's contracts.

我已经更改了 bean 的 java 类型,XMLGregorianCalendar直接在 xsd 的合同上添加了 jaxb 的配置。

I have done like this, note the xs:annotation:

我已经这样做了,请注意xs:annotation

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://hello.eomm.it/springws"
targetNamespace="http://hello.eomm.it/springws" elementFormDefault="qualified" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">

<xs:annotation> 
    <xs:appinfo>
        <jaxb:globalBindings>
            <jaxb:serializable uid="1" />
            <jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime"
                parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />
            <jaxb:javaType name="java.util.Calendar" xmlType="xs:date"
                parseMethod="javax.xml.bind.DatatypeConverter.parseDate" printMethod="javax.xml.bind.DatatypeConverter.printDate" />
            <jaxb:javaType name="java.util.Calendar" xmlType="xs:time"
                parseMethod="javax.xml.bind.DatatypeConverter.parseTime" printMethod="javax.xml.bind.DatatypeConverter.printTime" />
        </jaxb:globalBindings>
    </xs:appinfo>
</xs:annotation>


<xs:element name="getCountryRequest">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="name" type="xs:string" />
        </xs:sequence>
    </xs:complexType>
</xs:element>


<xs:element name="getCountryResponse">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="country" type="tns:country" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:complexType name="country">
    <xs:sequence>
        <xs:element name="name" type="xs:string" />
        <xs:element name="population" type="xs:int" />
        <xs:element name="capital" type="xs:string" />
        <xs:element name="foundation" type="xs:date" />
        <xs:element name="currency" type="tns:currency" />
    </xs:sequence>
</xs:complexType>

[...]

It is also needed to add the -Djavax.xml.accessExternalSchema=allparameter on JVM when you run the maven builds.

-Djavax.xml.accessExternalSchema=all运行 maven 构建时,还需要在 JVM上添加该参数。

回答by Julio Villane

The @vadim answer worked for me with a few additional details...

@vadim 的回答对我有用,还有一些额外的细节......

I was using spring boot 1.5.3 and the 2.3.1 version of the jaxb2-maven-plugin, and in that case I had to declare my xjb file as follows:

我使用的是 spring boot 1.5.3 和 jaxb2-maven-plugin 的 2.3.1 版本,在这种情况下,我必须如下声明我的 xjb 文件:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>xjc</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <packageName>...</packageName>
        <sources>
            <source>src/main/resources/file.xsd</source>
        </sources>
        <xjbSources>
            <xjbSource>src/main/resources/file.xjb</xjbSource>
        </xjbSources>
        <addGeneratedAnnotation>true</addGeneratedAnnotation>
        <locale>es</locale>
    </configuration>
</plugin>

In my case the xjb file content was:

在我的情况下,xjb 文件内容是:

<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
               jaxb:version="2.0"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc">
  <jaxb:globalBindings>
    <jaxb:serializable uid="1"/>
    <jaxb:javaType name="java.util.Date" xmlType="xsd:dateTime"
        parseMethod="package.path.bind.DataTypeConverter.parse"
        printMethod="package.path.bind.DataTypeConverter.print"/>
  </jaxb:globalBindings>
</jaxb:bindings>

And the DataTypeConverter content was:

而 DataTypeConverter 内容是:

import javax.xml.bind.DatatypeConverter;
import java.util.Calendar;
import java.util.Date;

public class DataTypeConverter {

    public static Date parse(String isoFormatDatetime) {
        return DatatypeConverter.parseDateTime(isoFormatDatetime).getTime();
    }
    public static String print(Date date) {
        return DatatypeConverter.printDateTime(toCalendar(date));
    }

    private static Calendar toCalendar(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }
}

Hope this helps someone!! :)

希望这对某人有帮助!!:)

回答by spy

This is probably a bit of a hack, but it works.

这可能有点黑客,但它有效。

After generating your code with wsimport, you can do a find and replace in files, replacing all references to XmlGregorianCalendar with java.util.Date. JAXB will happily do all the processing for you and automagically do the conversions. No adapters needed. I haven't ran into any problems using this method.

使用 wsimport 生成代码后,您可以在文件中进行查找和替换,用 java.util.Date 替换对 XmlGregorianCalendar 的所有引用。JAXB 很乐意为您完成所有处理并自动进行转换。不需要适配器。使用这种方法我没有遇到任何问题。