Spring Web Services ComponentAvailable as of Camel 2.6 The spring-ws: component allows you to integrate with Spring Web Services. It offers both client-side support, for accessing web services, and server-side 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>
URI formatThe 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:
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&... Options
Registry based optionsThe following options can be specified in the registry (most likely a Spring ApplicationContext) and referenced from the endpoint URI using the # notation.
Message headers
Accessing web servicesTo 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. Sending SOAP and WS-Addressing action headersWhen 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"); Using a custom MessageSender and MessageFactoryA 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> Exposing web servicesIn 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). Also don't forget to check out the Spring Web Services Example included in the Camel distribution. Endpoint mapping in routesWith 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) Alternative configuration, using existing endpoint mappingsFor 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.
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" /> POJO (un)marshallingCamel'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 pojo's, 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 POJO's 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); See Also |