The spring-ws: component allows you to integrate with Spring Web Services. It offers both clientside support, for accessing web services, and serverside support for creating your own contract-first web services.
Dependencies | |
---|---|
As of Camel 2.8 this component ships with Spring-WS 2.0.x which (like the rest of Camel) requires Spring 3.0.x. Earlier Camel versions shipped Spring-WS 1.5.9 which is compatible with Spring 2.5.x and 3.0.x. In order to run earlier versions of |
The URI scheme for this component is as follows
spring-ws:[mapping-type:]address[?options]
To expose a web service, mapping-type
needs to be set to one of the following
values:
Mapping type | Description |
---|---|
rootqname
|
Offers the option to map web service requests based on the qualified name of the root element contained in the message. |
soapaction
|
Used to map web service requests based on the SOAP action specified in the header of the message. |
uri
|
In order to map web service requests that target a specific URI. |
xpathresult
|
Used to map web service requests based on the evaluation of an XPath
expression against the incoming message. The result of the evaluation
should match the XPath result specified in the endpoint URI. |
beanname
|
Allows you to reference a
org.apache.camel.component.spring.ws.bean.CamelEndpointDispatcher in
order to integrate with existing (legacy) endpoint mappings like PayloadRootQNameEndpointMapping ,
SoapActionEndpointMapping , etc |
As a consumer the address
should contain a value relevant to the specified
mapping-type (e.g. a SOAP action, XPath expression). As a producer the address should be set
to the URI of the web service you are calling upon.
You can append query options to the URI in the following format,
?option=value&option=value&...
.
Name | Required? | Description |
---|---|---|
soapAction
|
No | SOAP action to include inside a SOAP request when accessing remote web services |
wsAddressingAction
|
No | WS-Addressing 1.0 action header to include when accessing web services. The
To header is set to the address of the web
service as specified in the endpoint URI (default Spring-WS behavior). |
expression
|
Only when mapping-type is xpathresult
|
XPath expression to use in the process of mapping web service requests, should match
the result specified by xpathresult
|
The following options can be specified in the registry (most likely a Spring application
context) and referenced from the endpoint URI using the
#
notation.beanID
Name | Required? | Description |
---|---|---|
webServiceTemplate
|
No | Option to provide a custom WebServiceTemplate. This allows for full control over client-side web services handling; like adding a custom interceptor or specifying a fault resolver, message sender or message factory. |
messageSender
|
No | Option to provide a custom WebServiceMessageSender. For example to perform authentication or use alternative transports |
messageFactory
|
No | Option to provide a custom WebServiceMessageFactory. For example when you want Apache Axiom to handle web service messages instead of SAAJ |
transformerFactory
|
No | Option to override the default TransformerFactory . The provided
transformer factory must be of type
javax.xml.transform.TransformerFactory
|
endpointMapping
|
Only when mapping-type is rootqname ,
soapaction , uri or xpathresult
|
Reference to
org.apache.camel.component.spring.ws.bean.CamelEndpointMapping in the
Registry/ApplicationContext. Only one bean is required in the registry to serve all
Camel/Spring-WS endpoints. This bean is auto-discovered by the MessageDispatcher and used to map requests to Camel endpoints based on
characteristics specified on the endpoint (like root QName, SOAP action, etc) |
Name | Type | Description |
---|---|---|
CamelSpringWebserviceEndpointUri
|
String
|
URI of the web service you are accessing as a client; overrides the address part of the endpoint URI. |
CamelSpringWebserviceSoapAction
|
String
|
Header to specify the SOAP action of the message; overrides the
soapAction option, if present |
CamelSpringWebserviceAddressingAction
|
URI
|
Use this header to specify the WS-Addressing action of the message; overrides the
wsAddressingAction option, if present |
To call a web service at
http://foo.com/bar
simply define a
route:
from("direct:example").to("spring-ws:http://foo.com/bar")
And sent a message:
template.requestBody("direct:example", "<foobar xmlns=\"http://foo.com\"><msg>test message</msg></foobar>");
Remember, if it's a SOAP service you're calling you don't have to include SOAP tags. Spring-WS will perform the XML-to-SOAP marshaling.
When a remote web service requires a SOAP action or use of the WS-Addressing standard you define your route as:
from("direct:example") .to("spring-ws:http://foo.com/bar?soapAction=http://foo.com&wsAddressingAction=http://bar.com")
Optionally you can override the endpoint options with header values:
template.requestBodyAndHeader("direct:example", "<foobar xmlns=\"http://foo.com\"><msg>test message</msg></foobar>", SpringWebserviceConstants.SPRING_WS_SOAP_ACTION, "http://baz.com");
A custom message sender or factory in the registry can be referenced like this:
from("direct:example") .to("spring-ws:http://foo.com/bar?messageFactory=#messageFactory&messageSender=#messageSender")
Spring configuration:
<!-- authenticate using HTTP Basic Authentication --> <bean id="messageSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSender"> <property name="credentials"> <bean class="org.apache.commons.httpclient.UsernamePasswordCredentials"> <constructor-arg index="0" value="admin"/> <constructor-arg index="1" value="secret"/> </bean> </property> </bean> <!-- force use of Sun SAAJ implementation, http://static.springsource.org/spring-ws/sites/1.5/faq.html#saaj-jboss --> <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"> <property name="messageFactory"> <bean class="com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl"></bean> </property> </bean>
In order to expose a web service using this component you first need to set-up a MessageDispatcher to look for endpoint mappings in a Spring XML file. If you plan on
running inside a servlet container you probably want to use a
MessageDispatcherServlet
configured in web.xml
.
By default the MessageDispatcherServlet
will look for a Spring XML
named /WEB-INF/spring-ws-servlet.xml
. To use Camel with Spring-WS the only
mandatory bean in that XML file is CamelEndpointMapping
. This bean allows
the MessageDispatcher
to dispatch web service requests to your routes.
web.xml
<web-app> <servlet> <servlet-name>spring-ws</servlet-name> <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring-ws</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
spring-ws-servlet.xml
<bean id="endpointMapping" class="org.apache.camel.component.spring.ws.bean.CamelEndpointMapping" /> <bean id="wsdl" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition"> <property name="schema"> <bean class="org.springframework.xml.xsd.SimpleXsdSchema"> <property name="xsd" value="/WEB-INF/foobar.xsd"/> </bean> </property> <property name="portTypeName" value="FooBar"/> <property name="locationUri" value="/"/> <property name="targetNamespace" value="http://example.com/"/> </bean>
More information on setting up Spring-WS can be found in Writing Contract-First Web Services.
With the XML configuration in-place you can now use Camel's DSL to define what web service
requests are handled by your endpoint. The following route will receive all web service
requests that have a root element named GetFoo
within the
http://example.com/
namespace:
from("spring-ws:rootqname:{http://example.com/}GetFoo?endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example)
The following route will receive web service requests containing the
http://example.com/GetFoo
SOAP action:
from("spring-ws:soapaction:http://example.com/GetFoo?endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example)
The following route will receive all requests sent to
http://example.com/foobar
:
from("spring-ws:uri:http://example.com/foobar?endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example)
The route below receives requests that contain the element
<foobar>abc</foobar>
anywhere inside the message (and the default
namespace).
from("spring-ws:xpathresult:abc?expression=//foobar&endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example)
For every endpoint with mapping-type beanname
one bean of type
CamelEndpointDispatcher
with a corresponding name is required in the
Registry/ApplicationContext. This bean acts as a bridge between the Camel endpoint and an
existing endpoint mapping like PayloadRootQNameEndpointMapping
.
Note | |
---|---|
The use of the |
An example of a route using beanname
:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="spring-ws:beanname:QuoteEndpointDispatcher" /> <to uri="mock:example" /> </route> </camelContext> <bean id="legacyEndpointMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping"> <property name="mappings"> <props> <prop key="{http://example.com/}GetFuture">FutureEndpointDispatcher</prop> <prop key="{http://example.com/}GetQuote">QuoteEndpointDispatcher</prop> </props> </property> </bean> <bean id="QuoteEndpointDispatcher" class="org.apache.camel.component.spring.ws.bean.CamelEndpointDispatcher" /> <bean id="FutureEndpointDispatcher" class="org.apache.camel.component.spring.ws.bean.CamelEndpointDispatcher" />
Camel's pluggable data formats offer support for POJO/XML marshalling using libraries such as JAXB, XStream, JibX, Castor and XMLBeans. You can use these data formats in your route to sent and receive POJOs (Plain Old Java Objects), to and from web services.
When accessing web services you can marshal the request and unmarshal the response message:
JaxbDataFormat jaxb = new JaxbDataFormat(false); jaxb.setContextPath("com.example.model"); from("direct:example").marshal(jaxb).to("spring-ws:http://foo.com/bar").unmarshal(jaxb);
Similarly when providing web services, you can unmarshal XML requests to POJOs and marshal the response message back to XML:
from("spring-ws:rootqname:{http://example.com/}GetFoo?endpointMapping=#endpointMapping").unmarshal(jaxb) .to("mock:example").marshal(jaxb);