Hello,
I'm trying to change one of our web services to a streaming web service as it
can generate quite a lot of data back.
My prototype implementation looks something like this:
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;
@WebServiceProvider(portName="PresentationServiceProviderPort",
serviceName="PresentationServiceProviderService",
targetNamespace="http://streamingps.bbb.aaa.com/")
@ServiceMode(value=Service.Mode.PAYLOAD)
public class PresentationServiceProviderImpl implements Provider<StreamSource>{
public PresentationServiceProviderImpl(){
}
@Override
public StreamSource invoke( StreamSource request ){
Map<String, String> parameters = parseRequest( request );
ResultsReader reader = new ResultsReader();
//Set the reader with the info from request
[snip]
StreamSource response = new StreamSource( reader );
return response;
}
WSDL file looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="wsdlformatter-doc-lit.xsl" type="text/xsl"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ps="http://streamingps.bbb.aaa.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
name="PresentationServiceProviderService"
targetNamespace="http://streamingps.bbb.aaa.com/">
<!-- TYPES -->
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ps="http://streamingps.bbb.aaa.com/"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://streamingps.bbb.aaa.com/">
[SNIP]
<xs:element name="streamingQB" type="ps:streamingQB"/>
<xs:complexType name="streamingQB">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1"
name="queryDefinition" type="xs:string" />
[SNIP]
</xs:sequence>
</xs:complexType>
<xs:element name="streamingQBResponse"
type="ps:streamingQBResponse"/>
<xs:complexType name="streamingQBResponse">
<xs:sequence>
<xs:element minOccurs="0" name="Presentation"
type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<!-- MESSAGES -->
<wsdl:message name="streamingQB">
<wsdl:part element="ps:streamingQB" name="parameters"/>
</wsdl:message>
<wsdl:message name="streamingQBResponse">
<wsdl:part element="ps:streamingQBResponse" name="parameters"/>
</wsdl:message>
<!-- PORT TYPE OPERATIONS -->
<wsdl:portType name="PresentationServiceProvider">
<wsdl:operation name="streamingQB">
<wsdl:input message="ps:streamingQB" name="streamingQB"/>
<wsdl:output message="ps:streamingQBResponse"
name="streamingQBResponse"/>
<wsdl:fault message="ps:PresentationServiceException" name="fault"/>
</wsdl:operation>
</wsdl:portType>
<!-- BINDING OPERATIONS -->
<wsdl:binding name="PresentationServiceProviderServiceSoapBinding"
type="ps:PresentationServiceProvider">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="streamingQB">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="streamingQB"><soap:body
use="literal"/></wsdl:input>
<wsdl:output name="streamingQBResponse"><soap:body
use="literal"/></wsdl:output>
<wsdl:fault name="fault"><soap:fault name="fault"
use="literal"/></wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<!-- WEB SERVICE -->
<wsdl:service name="PresentationServiceProviderService">
<wsdl:port binding="ps:PresentationServiceProviderServiceSoapBinding"
name="PresentationServiceProviderPort">
<soap:address
location="http://localhost:9944/services/ws/PresentationServiceProvider"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
In the beans.xml for the Spring configuration I've tried a number of things,
but it looks like this currently:
<jaxws:endpoint id="PresentationServiceProvider"
implementor="#presentationProviderService"
endpointName="e:PresentationServiceProviderPort"
serviceName="s:PresentationServiceProviderService"
address="/PresentationServiceProvider"
xmlns:e="http://service.jaxws.cxf.apache.org/endpoint"
xmlns:s="http://service.jaxws.cxf.apache.org/service"/>
This is the error I get:
22-Jun-2009 17:02:49 org.apache.cxf.interceptor.LoggingInInterceptor logging
INFO: Inbound Message
----------------------------
Encoding: UTF-8
Headers: {content-type=[text/xml;charset=UTF-8], Max-Forwards=[10],
host=[localhost:9944], Authorization=[Basic xxx], content-length=[908],
X-AuthenticatedUser=[mferrero], SOAPAction=[""], user-agent=[Jakarta
Commons-HttpClient/3.0.1], X-AuthenticatedSID=[xxx]}
Messages:
Message:
Payload: <soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:str="http://streamingps.bbb.aaa.com/">
<soapenv:Header/>
<soapenv:Body>
<str:streamingQB>
<str:queryDefinition><![CDATA[--query--]]></str:queryDefinition>
<str:datasourceId>1</str:datasourceId>
</str:streamingQB>
</soapenv:Body>
</soapenv:Envelope>
--------------------------------------
22-Jun-2009 17:02:49 org.apache.cxf.phase.PhaseInterceptorChain doIntercept
INFO: Application has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: object is not an instance of declaring class
while invoking public javax.xml.transform.stream.StreamSource
com.aaa.bbb.presentationservice.PresentationServiceProviderImpl.invoke(javax.xml.transform.stream.StreamSource)
with params [javax.xml.transform.stream.streamsou...@1f4a05d].
at
org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:112)
at
org.apache.cxf.jaxws.JAXWSMethodInvoker.createFault(JAXWSMethodInvoker.java:86)
at
org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:104)
at
org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:110)
at
org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:68)
at
org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:56)
at
org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
at
org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:92)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:221)
at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:77)
at
org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:92)
at
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:214)
at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:151)
at
org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:170)
at
org.apache.cxf.transport.servlet.AbstractCXFServlet.doPost(AbstractCXFServlet.java:148)
[snip]
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.IllegalArgumentException: object is not an instance of
declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:127)
at
org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:82)
... 63 more
It seems to me that something is wrong with the configuration and that somehow
CXF is processing the message instead of passing it to the low level provider.
Is there anything else I need to do to configure a Provider? I've struggle to
find information/examples in Nabble or the website.
At the moment we are running CXF 2.0.6.
Thanks a lot for your help,
Monica
________________________________
Accelrys Limited (http://accelrys.com)
Registered office: 334 Cambridge Science Park, Cambridge, CB4 0WN, UK
Registered in England: 2326316