...
Maven users will need to add the following dependency to their pom.xml
for this component:
Code Block | ||||
---|---|---|---|---|
| ||||
<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>
|
...
The URI scheme for this component is as follows
Code Block |
---|
spring-ws:[mapping-type:]address[?options]
|
...
Wiki Markup |
---|
{div:class=confluenceTableSmall} || Name || Required? || Description || | {{webServiceTemplate}} | No | Option to provide a custom [WebServiceTemplate|http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/client/core/WebServiceTemplate.html]. 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|http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/transport/WebServiceMessageSender.html]. For example to perform authentication or use alternative transports | | {{messageFactory}} | No | Option to provide a custom [WebServiceMessageFactory|http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/WebServiceMessageFactory.html]. 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 an instance of {{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|http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/server/MessageDispatcher.html] and used to map requests to Camel endpoints based on characteristics specified on the endpoint (like root QName, SOAP action, etc) | | {{messageFilter}} | No | *Camel 2.10.3* Option to provide a custom MessageFilter since 2.10.3. For example when you want to process your headers or attachments by your own. | {div} |
...
To call a web service at http://foo.com/bar
simply define a route:
Code Block |
---|
from("direct:example").to("spring-ws:http://foo.com/bar")
|
And sent a message:
Code Block |
---|
template.requestBody("direct:example", "<foobar xmlns=\"http://foo.com\"><msg>test message</msg></foobar>");
|
...
When a remote web service requires a SOAP action or use of the WS-Addressing standard you define your route as:
Code Block |
---|
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:
Code Block |
---|
template.requestBodyAndHeader("direct:example",
"<foobar xmlns=\"http://foo.com\"><msg>test message</msg></foobar>",
SpringWebserviceConstants.SPRING_WS_SOAP_ACTION, "http://baz.com");
|
...
You can provide the SOAP header(s) as a Camel Message header when sending a message to a spring-ws endpoint, for example given the following SOAP header in a String
Code Block |
---|
String body = ...
String soapHeader = "<h:Header xmlns:h=\"http://www.webserviceX.NET/\"><h:MessageID>1234567890</h:MessageID><h:Nested><h:NestedID>1111</h:NestedID></h:Nested></h:Header>";
|
We can set the body and header on the Camel Message as follows:
Code Block |
---|
exchange.getIn().setBody(body);
exchange.getIn().setHeader(SpringWebserviceConstants.SPRING_WS_SOAP_HEADER, soapHeader);
|
...
Spring WS Camel supports propagation of the headers and attachments into Spring-WS WebServiceMessage response since version 2.10.3.
The The endpoint will use so called "hook" the MessageFilter (default implementation is provided by BasicMessageFilter) to propagate the exchange headers and attachments into WebSdrviceMessage WebServiceMessage response.
Now Now you can use
Code Block |
---|
exchange.getOut().getHeaders().put("myCustom","myHeaderValue")
exchange.getIn().addAttachment("myAttachment", new DataHandler(...))
|
Note: If the exchange header in the pipeline contains text, it generates Qname(key)=value attribute in the soap header.
Recommended is to create a QName class directly and put into any key into header.
...
The BasicMessageFilter provides all required information for Apache Axiom in order to produce MTOM message. If you want to use Apache Camel Spring WS within Apache Axiom, here is an example:
1. Simply define the messageFactory as is bellow and springSpring-ws WS will use MTOM strategy to populate your SOAP message with optimized attachments.
Code Block |
---|
<bean id="axiomMessageFactory"
class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="false" />
<property name="attachmentCaching" value="true" />
<property name="attachmentCacheThreshold" value="1024" />
</bean>
|
2. Add into your pom.xml the following dependencies
Code Block |
---|
<dependency>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-api</artifactId>
<version>1.2.13</version>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-impl</artifactId>
<version>1.2.13</version>
<scope>runtime</scope>
</dependency>
|
3. Add your attachment into the pipeline, for example using a Processor implementation.
Code Block |
---|
private class Attachement implements Processor {
public void process(Exchange exchange) throws Exception
{ exchange.getOut().copyFrom(exchange.getIn()); File file = new File("testAttachment.txt"); exchange.getOut().addAttachment("test", new DataHandler(new FileDataSource(file))); }
}
|
4. Define endpoint (producer) as ussual, for example like this:
Code Block |
---|
from("direct:send")
.process(new Attachement())
.to("spring-ws:http://localhost:8089/mySoapService?soapAction=mySoap&messageFactory=axiomMessageFactory");
|
...
If you need to provide your custome custom processing of either headers or attachments, extend existing BasicMessageFilter and override the approchiate appropriate methods or write a brand new implementation of the MessageFilter interface.
To use your custom filter, add this into your spring context:
You can specify either a global a or a local message filter as follows:
a) the global custome custom filter that provides the global configuration for all springSpring-ws WS endpoints
Code Block |
---|
<bean id="messageFilter" class="your.domain.myMessageFiler" scope="singleton" /> |
or
b) the local messageFilter directly on the endpoint as follows:
Code Block |
---|
to("spring-ws:http://yourdomain.com?messageFilter=#myEndpointSpecificMessageFilter");
|
...
If you want to create your own MessageFilter, consider overrideing overriding the following methods in the default implementation of MessageFilter in class BasicMessageFilter:
Code Block |
---|
protected void doProcessSoapHeader(Message inOrOut, SoapMessage soapMessage) {your code /*no need to call super*/ } protected void doProcessSoapAttachements(Message inOrOut, SoapMessage response) { your code /*no need to call super*/ } |
...
A custom message sender or factory in the registry can be referenced like this:
Code Block |
---|
from("direct:example")
.to("spring-ws:http://foo.com/bar?messageFactory=#messageFactory&messageSender=#messageSender")
|
...
The following route will receive all web service requests that have a root element named "GetFoo" within the http://example.com/
namespace.
Code Block |
---|
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.
Code Block |
---|
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
.
Code Block |
---|
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).
Code Block |
---|
from("spring-ws:xpathresult:abc?expression=//foobar&endpointMapping=#endpointMapping")
.convertBodyTo(String.class).to(mock:example)
|
...
An example of a route using beanname
:
Code Block |
---|
<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" />
|
...
When accessing web services you can marshal the request and unmarshal the response message:
Code Block |
---|
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:
Code Block |
---|
from("spring-ws:rootqname:{http://example.com/}GetFoo?endpointMapping=#endpointMapping").unmarshal(jaxb)
.to("mock:example").marshal(jaxb);
|
Include Page | ||||
---|---|---|---|---|
|