I converted an Xfire SOAP Service to a CXF Simple Service.
My legacy XFire client can no longer call the new CXF service, but SOAPUI
works with both the old XFire and the new CXF server implementation.
When I call my service with my old Xfire client it fails to parse (gets a null
request object) this xfire client msg:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><readGadgetCompleteByKey
xmlns="http://widget.interfaces.service.abaserv.com"><in0
xmlns="http://widget.interfaces.service.abaserv.com"><bigText
xmlns="http://widget.pojo.abaserv.com" xsi:nil="true" /><bool
xmlns="http://widget.pojo.abaserv.com" xsi:nil="true" /><lockVersion
xmlns="http://widget.pojo.abaserv.com" xsi:nil="true" /><oid
xmlns="http://widget.pojo.abaserv.com">889</oid><smallText
xmlns="http://widget.pojo.abaserv.com" xsi:nil="true" /><smallnum
xmlns="http://widget.pojo.abaserv.com" xsi:nil="true"
/></in0></readGadgetCompleteByKey></soap:Body></soap:Envelope>
If I point SOAPUI to the same WSDL it generates this request which is processed
correctly by my new CXF SOAP Service:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wid="http://widget.interfaces.service.abaserv.com/">
<soapenv:Header/>
<soapenv:Body>
<wid:readGadgetCompleteByKey>
<arg0>
<oid>889</oid>
</arg0>
</wid:readGadgetCompleteByKey>
</soapenv:Body>
</soapenv:Envelope>
CXF should support SOAPui, CXF clients, and XFire clients.
Here's my cxf-servlet.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xmlns:simple="http://cxf.apache.org/simple"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/bindings/soap
http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd">
<simple:server id="widgetservice"
serviceClass="com.abaserv.service.interfaces.widget.WidgetServiceRead"
address="/WidgetService"
serviceBean="#widgetServiceImplTargetReadOnly"/>
</beans>
My service:
package com.abaserv.service.interfaces.widget;
import com.abaserv.pojo.widget.Gadget;
import com.abaserv.pojo.widget.Doodad;
import com.abaserv.service.ServiceException;
public interface WidgetServiceRead
{
Gadget readGadgetCompleteByKey(Gadget obj)
throws ServiceException;
Doodad readDoodadCompleteByKey(Doodad obj)
throws ServiceException;
}
My Pojo
package com.abaserv.pojo.widget;
import java.io.Serializable;
import org.apache.commons.lang.builder.ToStringBuilder;
public class Gadget implements Serializable
{
private static final long serialVersionUID = 1L;
Integer m_oid ;
Integer m_lockVersion ;
Integer m_smallnum ;
Boolean m_bool ;
String m_smallText ;
String m_bigText ;
java.util.Date m_timeStamp ;
public Integer getOid()
{
return m_oid;
}
public void setOid( Integer oid )
{
m_oid = oid;
}
public Integer getLockVersion()
{
return m_lockVersion;
}
public void setLockVersion( Integer lockVersion )
{
m_lockVersion = lockVersion;
}
public Integer getSmallnum()
{
return m_smallnum;
}
public void setSmallnum( Integer smallnum )
{
m_smallnum = smallnum;
}
public Boolean getBool()
{
return m_bool;
}
public void setBool( Boolean bool )
{
m_bool = bool;
}
public String getSmallText()
{
return m_smallText;
}
public void setSmallText( String smallText )
{
m_smallText = smallText;
}
public String getBigText()
{
return m_bigText;
}
public void setBigText( String bigText )
{
m_bigText = bigText;
}
public java.util.Date getTimeStamp()
{
return m_timeStamp;
}
public void setTimeStamp( java.util.Date timeStamp )
{
m_timeStamp = timeStamp;
}
@Override
public boolean equals(Object other) {
boolean result = false;
if ((other instanceof Gadget) && (other != null)) {
Gadget o = (Gadget) other;
result = (m_oid == o.m_oid);
}
return result;
}
@Override
public int hashCode() {
if (m_oid == null)
return 0;
return m_oid;
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="dashboard" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>WidgetWebService</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<init-param>
<param-name>config-location</param-name>
<param-value>WEB-INF/cxf-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/srv/*</url-pattern>
</servlet-mapping>
</web-app>
Sincerely,
Mike Lawrence
<?xml version="1.0" encoding="utf-8"?><wsdl:definitions
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://widget.interfaces.service.abaserv.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="WidgetServiceRead"
targetNamespace="http://widget.interfaces.service.abaserv.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://widget.interfaces.service.abaserv.com/"
attributeFormDefault="unqualified" elementFormDefault="unqualified"
targetNamespace="http://widget.interfaces.service.abaserv.com/">
<xs:complexType name="doodad">
<xs:sequence>
<xs:element minOccurs="0" name="lckVersion" type="xs:int"/>
<xs:element minOccurs="0" name="pkey" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="gadget">
<xs:sequence>
<xs:element minOccurs="0" name="bigText" type="xs:string"/>
<xs:element minOccurs="0" name="bool" type="xs:boolean"/>
<xs:element minOccurs="0" name="lockVersion" type="xs:int"/>
<xs:element minOccurs="0" name="oid" type="xs:int"/>
<xs:element minOccurs="0" name="smallText" type="xs:string"/>
<xs:element minOccurs="0" name="smallnum" type="xs:int"/>
<xs:element minOccurs="0" name="timeStamp" type="xs:dateTime"/>
</xs:sequence>
</xs:complexType>
<xs:element name="ServiceException" type="ServiceException"/>
<xs:complexType name="ServiceException">
<xs:sequence/>
</xs:complexType>
<xs:element name="readDoodadCompleteByKey" type="readDoodadCompleteByKey"/>
<xs:complexType name="readDoodadCompleteByKey">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="doodad"/>
</xs:sequence>
</xs:complexType>
<xs:element name="readDoodadCompleteByKeyResponse"
type="readDoodadCompleteByKeyResponse"/>
<xs:complexType name="readDoodadCompleteByKeyResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="doodad"/>
</xs:sequence>
</xs:complexType>
<xs:element name="readGadgetCompleteByKey" type="readGadgetCompleteByKey"/>
<xs:complexType name="readGadgetCompleteByKey">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="gadget"/>
</xs:sequence>
</xs:complexType>
<xs:element name="readGadgetCompleteByKeyResponse"
type="readGadgetCompleteByKeyResponse"/>
<xs:complexType name="readGadgetCompleteByKeyResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="gadget"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="readGadgetCompleteByKeyResponse">
<wsdl:part element="tns:readGadgetCompleteByKeyResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="readGadgetCompleteByKey">
<wsdl:part element="tns:readGadgetCompleteByKey" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="ServiceException">
<wsdl:part element="tns:ServiceException" name="ServiceException">
</wsdl:part>
</wsdl:message>
<wsdl:message name="readDoodadCompleteByKeyResponse">
<wsdl:part element="tns:readDoodadCompleteByKeyResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="readDoodadCompleteByKey">
<wsdl:part element="tns:readDoodadCompleteByKey" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="WidgetServiceReadPortType">
<wsdl:operation name="readDoodadCompleteByKey">
<wsdl:input message="tns:readDoodadCompleteByKey"
name="readDoodadCompleteByKey">
</wsdl:input>
<wsdl:output message="tns:readDoodadCompleteByKeyResponse"
name="readDoodadCompleteByKeyResponse">
</wsdl:output>
<wsdl:fault message="tns:ServiceException" name="ServiceException">
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="readGadgetCompleteByKey">
<wsdl:input message="tns:readGadgetCompleteByKey"
name="readGadgetCompleteByKey">
</wsdl:input>
<wsdl:output message="tns:readGadgetCompleteByKeyResponse"
name="readGadgetCompleteByKeyResponse">
</wsdl:output>
<wsdl:fault message="tns:ServiceException" name="ServiceException">
</wsdl:fault>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WidgetServiceReadSoapBinding"
type="tns:WidgetServiceReadPortType">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="readDoodadCompleteByKey">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="readDoodadCompleteByKey">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="readDoodadCompleteByKeyResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="ServiceException">
<soap:fault name="ServiceException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="readGadgetCompleteByKey">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="readGadgetCompleteByKey">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="readGadgetCompleteByKeyResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="ServiceException">
<soap:fault name="ServiceException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="WidgetServiceRead">
<wsdl:port binding="tns:WidgetServiceReadSoapBinding"
name="WidgetServiceReadPort">
<soap:address
location="https://api.outreachpartner.com:8443/svcsoapwidget20071101/srv/WidgetService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>