LibraryToggle FramesPrintFeedback

Available as of Camel 2.6

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.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
	<groupId>org.apache.camel</groupId>
	<artifactId>camel-spring-ws</artifactId>
	<version>x.x.x</version>
	<!-- use the same version as your Camel core version -->
</dependency>

[Important]Dependencies

This component offers support for Spring-WS 1.5.9 which is compatible with Spring 2.5.x and 3.0.x. In order to run camel-spring-ws on Spring 2.5.x you need to add the spring-webmvc module from Spring 2.5.x.

In order to run Spring-WS 1.5.9 on Spring 3.0 you need to exclude the OXM module from Spring 3.0 as this module is also included in Spring-WS 1.5.9 (see this post)

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 any of the following:

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 your 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 ApplicationContext) and referenced from the endpoint URI using the # notation.

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 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 your accessing as a client, overrides address part of the endpoint URI
CamelSpringWebserviceSoapAction String Header to specify the SOAP action of the message, overrides soapAction option if present
CamelSpringWebserviceAddressingAction URI Use this header to specify the WS-Addressing action of the message, overrides 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>");

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. Basically paragraph 3.6 "Implementing the Endpoint" is handled by this component (specifically paragraph 3.6.2 "Routing the Message to the Endpoint" is where CamelEndpointMapping comes in).

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 will receive 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]Note

The use of the beanname mapping-type is primarily meant for (legacy) situations where you're already using Spring-WS and have endpoint mappings defined in a Spring XML file. The beanname mapping-type allows you to wire your Camel route into an existing endpoint mapping. When you're starting from scratch it's recommended to define your endpoint mappings as Camel URI's (as illustrated above with endpointMapping) since it requires less configuration and is more expressive. Alternatively you could use vanilla Spring-WS with the help of annotations.

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" />

Comments powered by Disqus