我正在开发一个应用程序,我们使用Spring webservices使用wsdl生成的文件调用第三方SAP系统。
使用wsdl到ws import生成的文件之一具有类型为“XMLGregorianCalendar”的Date属性,作为响应,我们为相应的字段获取空值。
我想将日期从XmlGregorianCalendar转换为java.util.Date。
已提及:how replace XmlGregorianCalendar by Date? 但无法通过wsdl提供适当的xjb绑定。
如果有人可以建议转换由wsdl生成的日期,那将会有很大的帮助..... 提前致谢 ! 术赤
答案 0 :(得分:7)
WSDL与xjb无关。 xjb用于作为-b参数传递的xjc编译器。 即。
xjc -b <file>
如果你使用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>
或
<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>
依旧......
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>
正如您所看到的,它定义了从xsd:dateTime,xsd:date和xsd:time types到java.util.Calendar的转换。
我不建议使用java.util.Date。日期处理存在许多问题(特别是对于不同的时区)。 最好使用java.util.Calendar。日历更容易处理,JDK中有默认的转换器实现:
javax.xml.bind.DatatypeConverter
但是,如果您仍然想使用java.Util.Date,您需要拥有自己的小转换器,其中包含两个静态方法“parse”和“print”,然后将其设置为xjb。即。
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);
}
}
您在xjb中的转化将如下所示:
<jaxb:javaType name="java.util.Date" xmlType="xsd:dateTime"
parseMethod="MyDatatypeConverter.parse"
printMethod="MyDatatypeConverter.print" />
答案 1 :(得分:1)
您必须创建自定义数据类型适配器并添加绑定文件。
<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>
类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);
}
}
答案 2 :(得分:1)
我已经从XMLGregorianCalendar
更改了bean的java类型,直接在xsd的合同中添加了jaxb的配置。
我这样做了,请注意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>
[...]
运行maven构建时,还需要在JVM上添加-Djavax.xml.accessExternalSchema=all
参数。
答案 3 :(得分:1)
@vadim的答案对我来说有一些额外的细节......
我使用的是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>
就我而言,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>
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;
}
}
希望这有助于某人! :)
答案 4 :(得分:-2)
这可能有点像黑客,但它确实有效。
使用wsimport生成代码后,您可以在文件中执行查找和替换,将所有对XmlGregorianCalendar的引用替换为java.util.Date。 JAXB将很乐意为您完成所有处理并自动完成转换。无需适配器。我没有遇到任何使用这种方法的问题。