...
Spring
...
Web
...
Services
...
Component
...
Available
...
as
...
of
...
Camel
...
2.6
...
The
...
spring-ws:
...
component
...
allows
...
you
...
to
...
integrate
...
with
...
...
...
...
.
...
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:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <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> {code} {info:title=Dependencies}As of Camel |
Info | ||
---|---|---|
| ||
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 {{
on Spring 2.5.x you need to add the {{
module from Spring 2.5.x. In order to run Spring-WS 1.5.9 on Spring 3.0.x you need to exclude the OXM module from Spring 3.0.x as this module is also included in Spring-WS 1.5.9 (see [ |
URI format
The URI scheme for this component is as follows
Code Block |
---|
post|http://stackoverflow.com/questions/3313314/can-spring-ws-1-5-be-used-with-spring-3]) {info} h3. URI format The URI scheme for this component is as follows {code} spring-ws:[mapping-type:]address[?options] {code} |
To
...
expose
...
a
...
web
...
service
...
mapping-type
...
needs
...
to
...
be
...
set
...
to
...
any
...
of
...
the
...
following:
Div | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||
=confluenceTableSmall}
|| 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 an {{
|
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
Div | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}}
h3. Options
{div:class=confluenceTableSmall}
|| 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}} |
| {{timeout}} | No | *Camel 2.10:* Sets the socket read timeout (in milliseconds) while invoking a webservice using the producer, see [URLConnection.setReadTimeout()|http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html#setReadTimeout(int)] and [CommonsHttpMessageSender.setReadTimeout()|http://static.springsource.org/spring-ws/site/apidocs/org/springframework/ws/transport/http/CommonsHttpMessageSender.html#setReadTimeout(int)]. This option works when using the built-in message sender implementations: _CommonsHttpMessageSender_ and _HttpUrlConnectionMessageSender_. One of these implementations will be used by default for HTTP based services unless you customize the Spring WS configuration options supplied to the component. If you are using a non-standard sender, it is assumed that you will handle your own timeout configuration. |
| {{sslContextParameters}} | No | *Camel 2.10:* Reference to an {{
|
Message headers
Div | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||
|
Accessing web services
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") {code} |
And
...
sent
...
a
...
message:
Code Block |
---|
} template.requestBody("direct:example", "<foobar xmlns=\"http://foo.com\"><msg>test message</msg></foobar>"); {code} |
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
...
headers
...
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") {code} |
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"); {code} h3. Using SOAP headers *Available as of Camel "); |
Using SOAP headers
Available as of Camel 2.11.1
...
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>"; {code} |
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); {code} And then send the Exchange to a {{spring-ws}} endpoint to call theSOAP_HEADER, soapHeader); |
And then send the Exchange to a spring-ws
endpoint to call the Web Service.
Likewise the spring-ws consumer will also enrich the Camel Message with the SOAP header.
For an example see this unit test.
The header and attachment propagation
Spring WS Camel supports propagation of the headers and attachments into Spring-WS WebServiceMessage response since version 2.10.3. The endpoint will use so called "hook" the MessageFilter (default implementation is provided by BasicMessageFilter) to propagate the exchange headers and attachments into WebServiceMessage response. Now you can use
Code Block |
---|
Web Service. Likewise the spring-ws consumer will also enrich the Camel Message with the SOAP header. For an example see this [unit test|https://svn.apache.org/repos/asf/camel/trunk/components/camel-spring-ws/src/test/java/org/apache/camel/component/spring/ws/SoapHeaderTest.java]. h3. The header and attachment propagation Spring WS Camel supports propagation of the headers and attachments into Spring-WS WebServiceMessage response since version *2.10.3*. The endpoint will use so called "hook" the MessageFilter (default implementation is provided by BasicMessageFilter) to propagate the exchange headers and attachments into WebSdrviceMessage response. Now you can use {code} exchange.getOut().getHeaders().put("myCustom","myHeaderValue") exchange.getIn().addAttachment("myAttachment", new DataHandler(...)) {code} |
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.
...
How
...
to
...
use
...
MTOM
...
attachments
...
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
...
Spring-
...
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> {code} |
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> {code}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))); } } {code} |
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"); {code} |
5.
...
Now,
...
your
...
producer
...
will
...
generate
...
MTOM
...
message
...
with
...
otpmized
...
attachments.
...
The
...
custom
...
header
...
and
...
attachment
...
filtering
...
If
...
you
...
need
...
to
...
provide
...
your
...
custom processing
...
of
...
either
...
headers
...
or
...
attachments,
...
extend
...
existing
...
BasicMessageFilter
...
and
...
override
...
the
...
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
...
custom filter
...
that
...
provides
...
the
...
global
...
configuration
...
for
...
all
...
Spring-
...
WS endpoints
Code Block |
---|
} <bean id="messageFilter" class="your.domain.myMessageFiler" scope="singleton" /> {code} or |
or
b)
...
the
...
local
...
messageFilter
...
directly
...
on
...
the
...
endpoint
...
as
...
follows:
Code Block |
---|
} to("spring-ws:http://yourdomain.com?messageFilter=#myEndpointSpecificMessageFilter"); {code} |
For
...
more
...
information
...
see
...
If you want to create your own MessageFilter, consider overriding the following methods in the default implementation of MessageFilter in class BasicMessageFilter:
Code Block |
---|
|https://issues.apache.org/jira/browse/CAMEL-5724] If you want to create your own MessageFilter, consider overrideing the following methods in the default implementation of MessageFilter in class BasicMessageFilter: {code} 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*/ } |
Using a custom MessageSender and MessageFactory
A custom message sender or factory in the registry can be referenced like this:
Code Block |
---|
{code} h3. Using a custom MessageSender and MessageFactory A custom message sender or factory in the registry can be referenced like this: {code} from("direct:example") .to("spring-ws:http://foo.com/bar?messageFactory=#messageFactory&messageSender=#messageSender") {code} |
Spring
...
configuration:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml}<!-- authenticate using HTTP Basic Authentication --> <bean id="messageSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSenderHttpComponentsMessageSender"> <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> {code} h2. Exposing web services In order to expose a web service using this component you first need to set-up a [MessageDispatcher|http://static.springsource.org/spring-ws/sites/1.5/reference/html/server.html] 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 {{ |
Exposing web services
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
Code Block | ||||
---|---|---|---|---|
| ||||
_ {code: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> {code} _ |
spring-ws-servlet.xml
Code Block | ||||
---|---|---|---|---|
| ||||
_ {code: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> {code} |
More
...
information
...
on
...
setting
...
up
...
Spring-WS
...
can
...
be
...
found
...
in
...
...
...
...
...
.
...
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
...
...
...
...
...
included
...
in
...
the
...
Camel
...
distribution.
...
Endpoint
...
mapping
...
in
...
routes
...
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
...
...
namespace.
Code Block |
---|
} from("spring-ws:rootqname:{http://example.com/}GetFoo?endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example) {code} |
The
...
following
...
route
...
will
...
receive
...
web
...
service
...
requests
...
containing
...
the
...
...
SOAP
...
action.
Code Block |
---|
} from("spring-ws:soapaction:http://example.com/GetFoo?endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example) {code} |
The
...
following
...
route
...
will
...
receive
...
all
...
requests
...
sent
...
to
...
...
.
Code Block |
---|
} from("spring-ws:uri:http://example.com/foobar?endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example) {code} |
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) {code} h3. Alternative |
Alternative configuration,
...
using
...
existing
...
endpoint
...
mappings
...
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
...
...
...
like
...
PayloadRootQNameEndpointMapping
...
.
Note |
---|
} The use of the {{
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 {{
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 {{
) since it requires less configuration and is more expressive. Alternatively you could use vanilla Spring-WS with the help of annotations. {note} |
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" /> {code} h2. POJO |
POJO (un)marshalling
...
Camel's
...
...
...
...
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:
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); {code} |
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); {code} {include:Endpoint See Also} |
Include Page | ||||
---|---|---|---|---|
|