CXF 解组日期不接受 NULL 值
CXF unmarshalling Date not accepting NULL value
我有一个包含 -
的 WSDL 文件
<xs:complexType name="PNV">
<xs:sequence>
<xs:element name="dataType" type="xsd:int" />
<xs:element name="multiValued" type="xsd:boolean" />
<xs:element name="booleanValue" type="xsd:boolean" />
<xs:element name="dateValue" nillable="true" type="xsd:dateTime" />
..........
然后像这样转换成Java文件-
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PNV", propOrder = {
"dataType",
"multiValued",
"booleanValue",
"dateValue",
})
public class PNV
implements Serializable
{
private final static long serialVersionUID = 1L;
protected int dataType;
protected boolean multiValued;
protected boolean booleanValue;
@XmlElement(required = true, type = String.class, nillable = true)
@XmlJavaTypeAdapter(Adapter1 .class)
@XmlSchemaType(name = "dateTime")
protected Date dateValue;
}
绑定文件-
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://changeservice.xxservices.service.xx']">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:javaType name="java.util.Date" xmlType="xs:dateTime"
parseMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDateTime"
printMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.printDateTime"/>
<jxb:serializable uid="1"/>
</jxb:globalBindings>
</jaxws:bindings>
在我的 SOAPUI 测试用例中,我通过了 -
<dateValue nil="true"/>
但它给了我以下错误 -
Caused by: java.lang.IllegalArgumentException:
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parseAndSetYear(XMLGregorianCalendarImpl.java:2891) ~[na:1.8.0_201]
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parse(XMLGregorianCalendarImpl.java:2777) ~[na:1.8.0_201]
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl.<init>(XMLGregorianCalendarImpl.java:436) ~[na:1.8.0_201]
at com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl.newXMLGregorianCalendar(DatatypeFactoryImpl.java:536) ~[na:1.8.0_201]
at javax.xml.bind.DatatypeConverterImpl._parseDateTime(DatatypeConverterImpl.java:422) ~[na:1.8.0_201]
at javax.xml.bind.DatatypeConverterImpl.parseDateTime(DatatypeConverterImpl.java:417) ~[na:1.8.0_201]
at javax.xml.bind.DatatypeConverter.parseDateTime(DatatypeConverter.java:327) ~[na:1.8.0_201]
at org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDateTime(DataTypeAdapter.java:65) ~[cxf-xjc-runtime-3.3.1.jar:na]
at org.w3._2001.xmlschema.Adapter1.unmarshal(Adapter1.java:13) ~[classes/:na]
at org.w3._2001.xmlschema.Adapter1.unmarshal(Adapter1.java:1) ~[classes/:na]
at com.sun.xml.bind.v2.runtime.reflect.AdaptedAccessor.set(AdaptedAccessor.java:55) ~[jaxb-runtime-2.3.3.jar:2.3.3]
... 107 common frames omitted
我检查了 Adapter1 class 中的日期属性,它显示为空白而不是 null,因此它引发了错误。我的问题是为什么即使我在我的 SOAPUI 测试用例中传递了 nil=true,它也没有采用 NULL 值。为什么它是空白的?我还尝试从我的输入请求中完全删除这个 dateValue 字段,它仍然给我相同的日期字段错误。
我也尝试使用 XMLGregorianCalendar 作为 dateValue 的一种类型,但是当我在 SOAPUI 中传递 nil=true 时,它给了我同样的错误信息。请帮助。
这个 link 帮助了我:
https://blogs.oracle.com/rammenon/specifying-null-content-in-your-xml-document-using-nillable-and-xsi:nil
我在我的 SOAPUI 测试中添加了 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance 并添加了日期值
<dateValue xsi:nil="true"/>
如果您无法更改 wsdl 文件(以防由外部系统提供),您可以覆盖标准 org.apache.cxf.xjc.runtime.DataTypeAdapter
问题的根源不是 null,而是空字符串,作为 parseDateTime 方法的输入参数。
创建类似于“org.apache.cxf.xjc.runtime.DataTypeAdapter”的class,额外检查空字符串
public class DateAdapter {
public static Date parseDateTime(String s) {
if (s == null||s.isEmpty()) {
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);
}
}
在绑定文件中指定新的class
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://changeservice.xxservices.service.xx']">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:javaType name="java.util.Date" xmlType="xs:dateTime"
parseMethod="your_class_here.parseDateTime"
printMethod="your_class_here.printDateTime"/>
<jxb:serializable uid="1"/>
</jxb:globalBindings>
</jaxws:bindings>
我有一个包含 -
的 WSDL 文件<xs:complexType name="PNV">
<xs:sequence>
<xs:element name="dataType" type="xsd:int" />
<xs:element name="multiValued" type="xsd:boolean" />
<xs:element name="booleanValue" type="xsd:boolean" />
<xs:element name="dateValue" nillable="true" type="xsd:dateTime" />
..........
然后像这样转换成Java文件-
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PNV", propOrder = {
"dataType",
"multiValued",
"booleanValue",
"dateValue",
})
public class PNV
implements Serializable
{
private final static long serialVersionUID = 1L;
protected int dataType;
protected boolean multiValued;
protected boolean booleanValue;
@XmlElement(required = true, type = String.class, nillable = true)
@XmlJavaTypeAdapter(Adapter1 .class)
@XmlSchemaType(name = "dateTime")
protected Date dateValue;
}
绑定文件-
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://changeservice.xxservices.service.xx']">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:javaType name="java.util.Date" xmlType="xs:dateTime"
parseMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDateTime"
printMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.printDateTime"/>
<jxb:serializable uid="1"/>
</jxb:globalBindings>
</jaxws:bindings>
在我的 SOAPUI 测试用例中,我通过了 -
<dateValue nil="true"/>
但它给了我以下错误 -
Caused by: java.lang.IllegalArgumentException:
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parseAndSetYear(XMLGregorianCalendarImpl.java:2891) ~[na:1.8.0_201]
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parse(XMLGregorianCalendarImpl.java:2777) ~[na:1.8.0_201]
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl.<init>(XMLGregorianCalendarImpl.java:436) ~[na:1.8.0_201]
at com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl.newXMLGregorianCalendar(DatatypeFactoryImpl.java:536) ~[na:1.8.0_201]
at javax.xml.bind.DatatypeConverterImpl._parseDateTime(DatatypeConverterImpl.java:422) ~[na:1.8.0_201]
at javax.xml.bind.DatatypeConverterImpl.parseDateTime(DatatypeConverterImpl.java:417) ~[na:1.8.0_201]
at javax.xml.bind.DatatypeConverter.parseDateTime(DatatypeConverter.java:327) ~[na:1.8.0_201]
at org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDateTime(DataTypeAdapter.java:65) ~[cxf-xjc-runtime-3.3.1.jar:na]
at org.w3._2001.xmlschema.Adapter1.unmarshal(Adapter1.java:13) ~[classes/:na]
at org.w3._2001.xmlschema.Adapter1.unmarshal(Adapter1.java:1) ~[classes/:na]
at com.sun.xml.bind.v2.runtime.reflect.AdaptedAccessor.set(AdaptedAccessor.java:55) ~[jaxb-runtime-2.3.3.jar:2.3.3]
... 107 common frames omitted
我检查了 Adapter1 class 中的日期属性,它显示为空白而不是 null,因此它引发了错误。我的问题是为什么即使我在我的 SOAPUI 测试用例中传递了 nil=true,它也没有采用 NULL 值。为什么它是空白的?我还尝试从我的输入请求中完全删除这个 dateValue 字段,它仍然给我相同的日期字段错误。
我也尝试使用 XMLGregorianCalendar 作为 dateValue 的一种类型,但是当我在 SOAPUI 中传递 nil=true 时,它给了我同样的错误信息。请帮助。
这个 link 帮助了我: https://blogs.oracle.com/rammenon/specifying-null-content-in-your-xml-document-using-nillable-and-xsi:nil
我在我的 SOAPUI 测试中添加了 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance 并添加了日期值
<dateValue xsi:nil="true"/>
如果您无法更改 wsdl 文件(以防由外部系统提供),您可以覆盖标准 org.apache.cxf.xjc.runtime.DataTypeAdapter
问题的根源不是 null,而是空字符串,作为 parseDateTime 方法的输入参数。
创建类似于“org.apache.cxf.xjc.runtime.DataTypeAdapter”的class,额外检查空字符串
public class DateAdapter { public static Date parseDateTime(String s) { if (s == null||s.isEmpty()) { 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); }
}
在绑定文件中指定新的class
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://changeservice.xxservices.service.xx']">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:javaType name="java.util.Date" xmlType="xs:dateTime"
parseMethod="your_class_here.parseDateTime"
printMethod="your_class_here.printDateTime"/>
<jxb:serializable uid="1"/>
</jxb:globalBindings>
</jaxws:bindings>