CXF DynamicWebservice客户端dateTIme转换为XMLGregorianCalendar

时间:2016-10-05 13:21:01

标签: cxf webservice-client jaxb2

我的一个webservice参数是java.util.Date类型,当我生成CXF动态webservice客户端时,由于JAXB的默认行为,它被转换为XMLGregorianCalendar。但是,由于服务器上托管的Web服务需要Date对象,因此在调用实际Web服务时会抛出ClassCastException。

Caused by: java.lang.ClassCastException: java.util.Date cannot be cast to javax.xml.datatype.XMLGregorianCalendar
    at *.*.CloseSet_WrapperTypeHelper1.createWrapperObject(Unknown Source)
    at org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:103)
    ... 36 more

创建CXF动态Web服务客户端的代码如下:

private static JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory
            .newInstance();

...

private CachedClient getClient(String wsdlUrl) {
...
dcf.createClient(wsdlUrl, Arrays.asList(new String[]{"C:\\datebinding.xjb"}))
...
}

如果使用wsdl2java工具创建类,则使用相同的绑定文件,创建的类将字段显示为java.util.Date类型

C:\>"c:\apache-cxf-2.2.12\apache-cxf-2.2.12\bin\wsdl2java" -b datebinding.xjb http://localhost:8080/MyWeb/MyService?wsdl

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "closeSet", propOrder = {
    "instanceId",
    "activationDate"
})
public class CloseSet {

    protected long instanceId;
    @XmlElement(type = String.class)
    @XmlJavaTypeAdapter(Adapter1 .class)
    @XmlSchemaType(name = "dateTime")
    protected Date activationDate;

如果删除了绑定文件

C:\>"c:\apache-cxf-2.2.12\apache-cxf-2.2.12\bin\wsdl2java" http://localhost:8080/MyWeb/MyService?wsdl

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "closeSet", propOrder = {
    "instanceId",
    "activationDate"
})
public class CloseSet {

    protected long instanceId;
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar activationDate;

所以我怀疑我的自定义绑定文件没有被CXF动态客户端接收。

pom.xml中的CXF / JAXB依赖项

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-core</artifactId>
    <version>2.2.12</version>
</dependency>

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-ws-security</artifactId>
    <version>2.2.12</version>
</dependency>

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>2.2.12</version>
</dependency>

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>2.2.12</version>
</dependency>

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-xjc</artifactId>
    <version>2.1</version>
</dependency>

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.1</version>
</dependency>

在服务器上托管的Web服务

@WebService(endpointInterface = "com.*.*.configuration.IConfigWebService")
public class ConfigWebService

public void closeSet(long id, Date date)
            throws ObjectNotFoundException, DuplicateObjectException {

wsdl snippet - http://localhost:8080/MyWeb/MyService?wsdl

<wsdl:definitions xmlns:ns1="http://ws.*.*.*.com" xmlns:ns2="http://cxf.apache.org/bindings/xformat" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://impl.config.*.*.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ConfigWebServiceService" targetNamespace="http://impl.config.*.*.com/">
<wsdl:import location="http://localhost:8080/MyWeb/MyService?wsdl=IConfigWebService.wsdl" namespace="http://ws.*.*.*.com"></wsdl:import>
<wsdl:binding name="ConfigWebServiceServiceSoapBinding" type="ns1:IConfigWebService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>

<wsdl:operation name="closeSet">
    <soap:operation soapAction="" style="document"/>
    <wsdl:input name="closeSet">
        <soap:body use="literal"/>
    </wsdl:input>
    <wsdl:output name="closeSetResponse">
        <soap:body use="literal"/>
    </wsdl:output>

http://localhost:8080/MyWeb/ConfigService?wsdl=IConfigWebService.wsdl

<wsdl:definitions xmlns:ns1="http://ws.*.*.*.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IConfigWebService" targetNamespace="http://ws.*.*.*.com">
    <wsdl:types>
        <xs:schema xmlns:tns="http://ws.*.*.*.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://ws.*.*.*.com">

            <xs:element name="closeSet" type="tns:closeSet"/>
            <xs:element name="closeSetResponse" type="tns:closeSetResponse"/>

            <xs:complexType name="closeSet">
                <xs:sequence>
                    <xs:element name="instanceId" type="xs:long"/>
                    <xs:element minOccurs="0" name="activationDate" type="xs:dateTime"/>
                </xs:sequence>
            </xs:complexType>

1 个答案:

答案 0 :(得分:0)

通过将工厂类从JaxWsDynamicClientFactory更改为DynamicClientFactory,我能够生成动态客户端,并将datetime字段映射到java Date。仍然不确定为什么它不适用于JaxWsDynamicClientFactory;)