0% found this document useful (0 votes)
51 views

3 - Reference Documentation

The document provides information about Spring Web Services including: - It discusses full streaming support in AXIOM for returning JAXB objects from handler methods. - It describes how to configure the SOAP version (1.1 or 1.2) used in SaajSoapMessageFactory and AxiomSoapMessageFactory. - It introduces key concepts in Spring Web Services like MessageContext, TransportContext, and handling XML with XPathExpression and XPathTemplate.

Uploaded by

Neemias Júnior
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
51 views

3 - Reference Documentation

The document provides information about Spring Web Services including: - It discusses full streaming support in AXIOM for returning JAXB objects from handler methods. - It describes how to configure the SOAP version (1.1 or 1.2) used in SaajSoapMessageFactory and AxiomSoapMessageFactory. - It introduces key concepts in Spring Web Services like MessageContext, TransportContext, and handling XML with XPathExpression and XPathTemplate.

Uploaded by

Neemias Júnior
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

09/03/2022 08:45 Spring Web Services Reference Documentation

written
to a DOM tree or buffer.

Full streaming for AXIOM is used when a handler method returns a


JAXB2-supported object.
It will automatically set this
marshalled object into the response message, and write it out to
the outgoing socket stream when the response is going out.

For more information about full streaming, refer to the class-level Javadoc for
StreamingWebServiceMessage and
StreamingPayload .

SOAP 1.1 or 1.2

Both the SaajSoapMessageFactory and the


AxiomSoapMessageFactory have a soapVersion property,
where you can inject
a SoapVersion constant. By default, the version
is 1.1, but you can set it to 1.2 like so:

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:util="http://www.springframework.org/schema/util"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/util

http://www.springframework.org/schema/util/spring-util-2.0.xsd">

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">

<property name="soapVersion">

<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_12"/>

</property>

</bean>

</beans>

In the example above, we define a SaajSoapMessageFactory that only accepts


SOAP 1.2 messages.

Caution

Even though both versions of SOAP are quite similar in format, the 1.2
version is not backwards
compatible with 1.1 because it uses a different XML namespace.
Other major differences between
SOAP 1.1 and 1.2 include the different structure
of a Fault, and the fact that SOAPAction HTTP
headers are effectively
deprecated, thought they still work.

One important thing to note with SOAP version numbers, or WS-* specification
version numbers in
general, is that the latest version of a specification is
generally not the most popular version.
For SOAP,
this means that currently, the best version to use is 1.1.
Version 1.2 might become more popular in the
future, but currently 1.1 is the safest bet.

4.1.4  MessageContext
Typically, messages come in pairs: a request and a response. A request is created on the client-side,
which is sent over some
transport to the server-side, where a response is generated. This response gets
sent back to the client, where it is read.

In Spring Web Services, such a conversation is contained in a


MessageContext , which has properties to get request and
response
messages.
On the client-side, the message context is created by the WebServiceTemplate .
On the server-side, the
message context is read from the transport-specific input stream.
For example, in HTTP, it is read from the
HttpServletRequest and the
response is written back to the HttpServletResponse .

4.2  TransportContext
One of the key properties of the SOAP protocol is that it tries to be transport-agnostic. This is why, for
instance, Spring-WS does
not support mapping messages to endpoints by HTTP request URL, but
rather by mesage content.

https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 20/71
09/03/2022 08:45 Spring Web Services Reference Documentation

However, sometimes it is necessary to get access to the underlying transport, either on the client or server
side. For this, Spring
Web Services has the TransportContext . The transport
context allows access to the underlying WebServiceConnection ,
which typically
is a HttpServletConnection on the server side; or a
HttpUrlConnection or CommonsHttpConnection on
the client side.
For example, you can obtain the IP address of the current request in a server-side endpoint or
interceptor like so:

TransportContext context = TransportContextHolder.getTransportContext();

HttpServletConnection connection = (HttpServletConnection )context.getConnection();

HttpServletRequest request = connection.getHttpServletRequest();

String ipAddress = request.getRemoteAddr();

4.3 Handling XML With XPath


One of the best ways to handle XML is to use XPath.
Quoting [effective-xml], item 35:

  XPath is a fourth generation declarative language that allows you to specify which nodes you want  
to
process without specifying exactly how the processor is supposed to navigate to those nodes.
XPath's
data model is very well designed to support exactly what almost all developers want from
XML. For
instance, it merges all adjacent text including that in CDATA sections, allows values to be
calculated that skip over comments and processing instructions` and include text from child and
descendant elements, and requires all external entity references to be resolved. In practice, XPath
expressions tend to be much more robust against unexpected but perhaps insignificant changes in
the
input document.

  --Elliotte Rusty Harold

Spring Web Services has two ways to use XPath within your application: the faster
XPathExpression or the more flexible
XPathTemplate .

4.3.1  XPathExpression
The XPathExpression is an abstraction over a compiled XPath expression,
such as the Java 5
javax.xml.xpath.XPathExpression , or the Jaxen
XPath class.
To construct an expression in an application context, there is
the
XPathExpressionFactoryBean . Here is an example which uses this factory bean:

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="nameExpression" class="org.springframework.xml.xpath.XPathExpressionFactoryBean">

<property name="expression" value="/Contacts/Contact/Name"/>

</bean>

<bean id="myEndpoint" class="sample.MyXPathClass">

<constructor-arg ref="nameExpression"/>

</bean>

</beans>

The expression above does not use namespaces, but we could set those using the
namespaces property of the factory bean.
The expression
can be used in the code as follows:

package sample;

public class MyXPathClass {

private final XPathExpression nameExpression;

public MyXPathClass(XPathExpression nameExpression) {

this.nameExpression = nameExpression;

https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 21/71
09/03/2022 08:45 Spring Web Services Reference Documentation
p p
}

public void doXPath(Document document) {

String name = nameExpression.evaluateAsString(document.getDocumentElement());


System.out.println("Name: " + name);

For a more flexible approach, you can use a NodeMapper , which is similar
to the RowMapper in Spring's JDBC support. The
following
example shows how we can use it:

package sample;

public class MyXPathClass {

private final XPathExpression contactExpression;

public MyXPathClass(XPathExpression contactExpression) {

this.contactExpression = contactExpression;

public void doXPath(Document document) {

List contacts = contactExpression.evaluate(document,

new NodeMapper() {

public Object mapNode(Node node, int nodeNum) throws DOMException {

Element contactElement = (Element) node;

Element nameElement = (Element) contactElement.getElementsByTagName("Name").item(0);

Element phoneElement = (Element) contactElement.getElementsByTagName("Phone").item(0);

return new Contact(nameElement.getTextContent(), phoneElement.getTextContent());

});

// do something with list of Contact objects

Similar to mapping rows in Spring JDBC's RowMapper , each result node is


mapped using an anonymous inner class. In this
case, we create a Contact object,
which we use later on.

4.3.2  XPathTemplate
The XPathExpression only allows you to evaluate a single, pre-compiled
expression. A more flexible, though slower,
alternative is the XpathTemplate .
This class follows the common template pattern used throughout Spring (JdbcTemplate,
JmsTemplate, etc.).
Here is an example:

package sample;

public class MyXPathClass {

private XPathOperations template = new Jaxp13XPathTemplate();

public void doXPath(Source source) {

String name = template.evaluateAsString("/Contacts/Contact/Name", request);

// do something with name

4.4 Message Logging and Tracing


When developing or debugging a Web service, it can be quite useful to look at the content of a (SOAP)
message when it arrives,
or just before it is sent. Spring Web Services offer this functionality, via the
standard Commons Logging interface.

https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 22/71
09/03/2022 08:45 Spring Web Services Reference Documentation

Caution

Make sure to use Commons Logging version 1.1 or higher. Earlier versions have class loading issues,
and
do not integrate with the Log4J TRACE level.

To log all server-side messages, simply set the


org.springframework.ws.server.MessageTracing logger to level DEBUG
or TRACE. On the debug
level, only the payload root element is logged; on the TRACE level, the entire message content.
If you
only want to log sent messages, use the
org.springframework.ws.server.MessageTracing.sent logger; or
org.springframework.ws.server.MessageTracing.received to log received messages.

On the client-side, similar loggers exist:


org.springframework.ws.client.MessageTracing.sent and
org.springframework.ws.client.MessageTracing.received .

Here is an example log4j.properties configuration, logging the full content of


sent messages on the client side, and only the
payload root element for client-side received messages. On
the server-side, the payload root is logged for both sent and
received messages:

log4j.rootCategory=INFO, stdout

log4j.logger.org.springframework.ws.client.MessageTracing.sent=TRACE

log4j.logger.org.springframework.ws.client.MessageTracing.received=DEBUG

log4j.logger.org.springframework.ws.server.MessageTracing=DEBUG

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%p [%c{3}] %m%n

With this configuration, a typical output will be:

TRACE [client.MessageTracing.sent] Sent request [<SOAP-ENV:Envelope xmlns:SOAP-ENV="...

DEBUG [server.MessageTracing.received] Received request [SaajSoapMessage {http://example.com}request] ...

DEBUG [server.MessageTracing.sent] Sent response [SaajSoapMessage {http://example.com}response] ...

DEBUG [client.MessageTracing.received] Received response [SaajSoapMessage {http://example.com}response] ...

5. Creating a Web service with Spring-WS

5.1 Introduction
Spring-WS's server-side support is designed around a
MessageDispatcher that dispatches incoming
messages to endpoints,
with configurable endpoint mappings, response
generation, and endpoint interception.
Endpoints are typically annotated with the
@Endpoint annotation, and have
one or more handling methods.
These methods handle incoming XML request messages by
inspecting parts of the message (typically the
payload), and create some sort of response.
You annotate the method with another
annotation, typically @PayloadRoot ,
to indicate what sort of messages it can handle.

Spring-WS's XML handling is extremely flexible. An endpoint can choose from


a large amount of XML handling libraries
supported by Spring-WS, including the DOM family (W3C DOM, JDOM,
dom4j, and XOM), SAX or StAX for faster performance,
XPath to extract information from the message, or even
marshalling techniques (JAXB, Castor, XMLBeans, JiBX, or XStream) to
convert
the XML to objects and vice-versa.

5.2 The MessageDispatcher
The server-side of Spring-WS is designed around a central class that dispatches incoming XML messages to
endpoints. Spring-
WS's MessageDispatcher is extremely flexible, allowing you to
use any sort of class as an endpoint, as long as it can be
configured in the Spring IoC container.
In a way, the message dispatcher resembles Spring's DispatcherServlet , the
“Front
Controller” used in Spring Web MVC.

The processing and dispatching flow of the MessageDispatcher is illustrated in the


following sequence diagram.

https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 23/71
09/03/2022 08:45 Spring Web Services Reference Documentation

The request processing workflow in Spring Web Services

When a MessageDispatcher is set up for use and a request comes in for that
specific dispatcher, said MessageDispatcher
starts processing the request. The
list below describes the complete process a request goes through when handled by a
MessageDispatcher :

1. An appropriate endpoint is searched for using the configured EndpointMapping(s) .


If an endpoint is found, the invocation
chain associated with the endpoint (pre-processors,
post-processors, and endpoints) will be executed in order to create a
response.
2. An appropriate adapter is searched for the endpoint. The MessageDispatcher
delegates to this adapter to invoke the
endpoint.
3. If a response is returned, it is sent on its way. If no response is returned (which could be due to
a pre- or post-processor
intercepting the request, for example, for security reasons), no response
is sent.

Exceptions that are thrown during handling of the request get picked up by any of the endpoint exception
resolvers that are
declared in the application context. Using these exception resolvers allows you to define
custom behaviors (such as returning a
SOAP Fault) in case such exceptions get thrown.

The MessageDispatcher has several properties, for setting endpoint adapters,


mappings,
exception resolvers.
However,
setting these properties is not required, since the dispatcher will automatically detect all of
these types that are registered in the
application context. Only when detection needs to be overriden,
should these properties be set.

The message dispatcher operates on a message context, and not


transport-specific input stream and output stream. As a result,
transport specific requests need to read
into a MessageContext . For HTTP, this is done with a
WebServiceMessageReceiverHandlerAdapter , which is a Spring Web
HandlerInterceptor , so that the
MessageDispatcher
can be wired in a standard DispatcherServlet . There is a more convenient way to do
this, however,
which is shown in Section 5.3.1, “ MessageDispatcherServlet ”.

5.3 Transports
Spring Web Services supports multiple transport protocols. The most common is the HTTP transport, for which
a custom servlet
is supplied, but it is also possible to send messages over JMS, and even email.

5.3.1  MessageDispatcherServlet
The MessageDispatcherServlet is a standard Servlet
which
conveniently extends from the standard Spring Web
DispatcherServlet , and wraps
a MessageDispatcher . As such, it combines the attributes of these into one:
as a
MessageDispatcher , it follows the same request handling flow as described
in the previous section.
As a servlet, the
MessageDispatcherServlet is configured in the web.xml of
your web application. Requests that you want the
MessageDispatcherServlet to
handle will have to be mapped using a URL mapping in the same web.xml file. This is
standard Java EE servlet configuration; an example of such a
MessageDispatcherServlet declaration and mapping can be
found below.

<web-app>

<servlet>

<servlet-name>spring-ws</servlet-name>

<servlet-class>org springframework ws transport http MessageDispatcherServlet</servlet-class>


https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 24/71
09/03/2022 08:45 Spring Web Services Reference Documentation
<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>

In the example above, all requests will be handled by the 'spring-ws'


MessageDispatcherServlet . This is only the first
step in setting up Spring Web
Services, because the various component beans used by the Spring-WS framework also need to
be
configured; this configuration consists of standard Spring XML <bean/>
definitions. Because the
MessageDispatcherServlet is a standard Spring
DispatcherServlet , it will look for a file named
[servlet-name]-servlet.xml in the WEB-INF directory
of your web application and create the beans defined there in a
Spring container. In the example above,
that means that it looks for ' /WEB-INF/spring-ws-servlet.xml '. This file will
contain
all of the Spring Web Services beans such as endpoints, marshallers and suchlike.

As an alternative for web.xml , if you are running on a Servlet 3+ environment, you


can configure Spring-WS programmatically.
For this purpose, Spring-WS provides a number of abstract base classes that extend the
WebApplicationInitializer
interface found in the Spring Framework.
If you are also using @Configuration classes for your bean definitions, you are
best
of extending the AbstractAnnotationConfigMessageDispatcherServletInitializer , like so:

public class MyServletInitializer

extends AbstractAnnotationConfigMessageDispatcherServletInitializer {

@Override

protected Class<?>[] getRootConfigClasses() {

return new Class[]{MyRootConfig.class};

@Override

protected Class<?>[] getServletConfigClasses() {

return new Class[]{MyEndpointConfig.class};

In the example above, we tell Spring that endpoint bean definitions can be found in the MyEndpointConfig
class (which is a
@Configuration class).
Other bean definitions (typically services, repositories, etc.) can be found in the MyRootConfig
class.
By default, the AbstractAnnotationConfigMessageDispatcherServletInitializer maps the servlet to
two patterns:
/services and *.wsdl , though this can be changed by overriding the
getServletMappings() method.
For more details on
the programmatic configuration of the MessageDispatcherServlet , refer to the
Javadoc of
AbstractMessageDispatcherServletInitializer and
AbstractAnnotationConfigMessageDispatcherServletInitializer .

Automatic WSDL exposure

The MessageDispatcherServlet will automatically detect any


WsdlDefinition beans defined in it's Spring container. All
such
WsdlDefinition beans that are detected will also be exposed via
a WsdlDefinitionHandlerAdapter ; this is a very
convenient way to expose your
WSDL to clients simply by just defining some beans.

By way of an example, consider the following <static-wsdl> definition,


defined in the Spring-WS configuration file
( /WEB-INF/[servlet-name]-servlet.xml ).
Take notice of the value of the ' id ' attribute, because this will be used when
exposing the WSDL.

<sws:static-wsdl id="orders" location="orders.wsdl"/>

Or as @Bean method in a @Configuration class:

@Bean

public SimpleWsdl11Definition orders() {


https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 25/71
09/03/2022 08:45 Spring Web Services Reference Documentation
public SimpleWsdl11Definition orders() {

return new SimpleWsdl11Definition(new ClassPathResource("orders.xml"));

The WSDL defined in the ' orders.wsdl ' file on the classpath can then be accessed via
GET requests to a URL of the following
form (substitute the host, port and
servlet context path as appropriate).

http://localhost:8080/spring-ws/orders.wsdl

All WsdlDefinition bean definitions are exposed by the


MessageDispatcherServlet under their bean name
with the
suffix .wsdl .
So if the bean name is echo , the host name is "server", and the Servlet
context (war name)
is "spring-ws", the WSDL can be obtained via
http://server/spring-ws/echo.wsdl

Another nice feature of the MessageDispatcherServlet (or more correctly the


WsdlDefinitionHandlerAdapter ) is that it is
able to
transform the value of the ' location ' of all the WSDL that it exposes to reflect
the URL of the incoming request.

Please note that this ' location ' transformation feature is


off by default.To switch this feature on, you just need to specify an
initialization parameter to the MessageDispatcherServlet , like so:

<web-app>

<servlet>

<servlet-name>spring-ws</servlet-name>

<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>

<init-param>

<param-name>transformWsdlLocations</param-name>

<param-value>true</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>spring-ws</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

</web-app>

If you use the AbstractAnnotationConfigMessageDispatcherServletInitializer ,


enabling transformation is as simple as
overriding the isTransformWsdlLocations()
method to return true .

Consult the class-level Javadoc on the WsdlDefinitionHandlerAdapter class


to learn more about the whole transformation
process.

As an alternative to writing the WSDL by hand, and exposing it with


<static-wsdl> , Spring Web Services can also generate a
WSDL
from an XSD schema.
This is the approach shown in Section 3.7, “Publishing the WSDL”.
The next application context
snippet shows how to create such a dynamic WSDL file:

<sws:dynamic-wsdl id="orders"

portTypeName="Orders"

locationUri="http://localhost:8080/ordersService/">

<sws:xsd location="Orders.xsd"/>

</sws:dynamic-wsdl>

Or, as @Bean method:

@Bean

public DefaultWsdl11Definition orders() {

DefaultWsdl11Definition definition = new DefaultWsdl11Definition();

definition.setPortTypeName("Orders");

definition.setLocationUri("http://localhost:8080/ordersService/");

definition.setSchema(new SimpleXsdSchema(new ClassPathResource("echo.xsd")));

https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 26/71
09/03/2022 08:45 Spring Web Services Reference Documentation
return definition;

The <dynamic-wsdl> element depends on the


DefaultWsdl11Definition class.
This definition class uses WSDL providers
in the
org.springframework.ws.wsdl.wsdl11.provider package and the
ProviderBasedWsdl4jDefinition
to generate a WSDL
the first time it is requested.
Refer to the class-level Javadoc of these classes to see how you can extend this mechanism,
if
necessary.

The DefaultWsdl11Definition (and therefore, the <dynamic-wsdl> tag)


builds a WSDL from a XSD schema by using
conventions.
It iterates over all element elements
found in the schema, and creates a message for all elements.
Next, it
creates WSDL operation for all messages that end with the
defined request or response suffix.
The default request suffix is
Request ;
the default response suffix is Response , though these can be changed by
setting the requestSuffix and
responseSuffix
attributes on <dynamic-wsdl /> , respectively.
It also builds a portType , binding , and
service based on
the operations.

For instance, if our Orders.xsd schema defines the


GetOrdersRequest and GetOrdersResponse elements,
<dynamic-wsdl> will create a
GetOrdersRequest and GetOrdersResponse message, and a
GetOrders operation, which
is put in a Orders port type.

If you want to use multiple schemas, either by includes or imports, you will want to
put Commons XMLSchema on the class path.
If Commons XMLSchema is on the class path, the above <dynamic-wsdl>
element will follow all XSD imports and includes,
and will inline them in the WSDL as a single XSD.
This greatly simplifies the deployment of the schemas, which still making it
possible to edit them
separately.

Caution

Even though it can be quite handy to create the WSDL at runtime from your XSDs, there
are a couple of
drawbacks to this approach. First off, though we try to keep the WSDL generation
process consistent
between releases, there is still the possibility that it changes (slightly).
Second, the generation is a bit
slow, though once generated, the WSDL is cached for later
reference.

It is therefore recommended to only use <dynamic-wsdl>


during the development stages of your
project.
Then, we recommend to use your browser to download the generated WSDL, store it in the
project,
and expose it with <static-wsdl> .
This is the only way to be really sure that the WSDL does
not change over time.

5.3.2 Wiring up Spring-WS in a DispatcherServlet


As an alternative to the MessageDispatcherServlet , you can wire up a
MessageDispatcher in a standard, Spring-Web
MVC
DispatcherServlet .
By default, the DispatcherServlet can only delegate to
Controllers , but we can instruct it to
delegate to a
MessageDispatcher by adding a
WebServiceMessageReceiverHandlerAdapter to the servlet's web
application
context:

<beans>

<bean class="org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter"/>

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="defaultHandler" ref="messageDispatcher"/>

</bean

<bean id="messageDispatcher" class="org.springframework.ws.soap.server.SoapMessageDispatcher"/>

...

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

</beans>

https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 27/71
09/03/2022 08:45 Spring Web Services Reference Documentation

Note that by explicitly adding the WebServiceMessageReceiverHandlerAdapter ,


the dispatcher servlet does not load the
default adapters, and is unable to handle standard Spring-MVC
@Controllers . Therefore, we add the
RequestMappingHandlerAdapter at the end.

In a similar fashion, you can wire up a WsdlDefinitionHandlerAdapter to make sure


the DispatcherServlet can handle
implementations of the
WsdlDefinition interface:

<beans>

<bean class="org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter"/>

<bean class="org.springframework.ws.transport.http.WsdlDefinitionHandlerAdapter"/>

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="mappings">

<props>

<prop key="*.wsdl">myServiceDefinition</prop>

</props>

</property>

<property name="defaultHandler" ref="messageDispatcher"/>

</bean>

<bean id="messageDispatcher" class="org.springframework.ws.soap.server.SoapMessageDispatcher"/>

<bean id="myServiceDefinition" class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">

<prop name="wsdl" value="/WEB-INF/myServiceDefintion.wsdl"/>

</bean>

...

</beans>

5.3.3 JMS transport
Spring Web Services supports server-side JMS handling through the JMS functionality provided in the
Spring framework. Spring
Web Services provides the WebServiceMessageListener
to plug in to a MessageListenerContainer . This message listener
requires a
WebServiceMessageFactory to and
MessageDispatcher to operate. The following piece of configuration
shows
this:

<beans>

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

<property name="brokerURL" value="vm://localhost?broker.persistent=false"/>

</bean>

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">

<property name="connectionFactory" ref="connectionFactory"/>

<property name="destinationName" value="RequestQueue"/>

<property name="messageListener">

<bean class="org.springframework.ws.transport.jms.WebServiceMessageListener">

<property name="messageFactory" ref="messageFactory"/>

<property name="messageReceiver" ref="messageDispatcher"/>

</bean>

</property>

</bean>

<bean id="messageDispatcher" class="org.springframework.ws.soap.server.SoapMessageDispatcher">

<property name="endpointMappings">

<bean

class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping
<property name="defaultEndpoint">

<bean class="com.example.MyEndpoint"/>

https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 28/71
09/03/2022 08:45 Spring Web Services Reference Documentation
</property>

</bean>

</property>

</bean>

</beans>

5.3.4 Email transport
In addition to HTTP and JMS, Spring Web Services also provides server-side email handling. This
functionality is provided
through the MailMessageReceiver class. This class
monitors a POP3 or IMAP folder, converts the email to a
WebServiceMessage ,
sends any response using SMTP. The host names can be configured through the
storeUri, which
indicates the mail folder to monitor for requests (typically a POP3 or IMAP folder),
and a transportUri, which indicates the server
to use for sending responses (typically a SMTP server).

How the MailMessageReceiver monitors incoming messages can be configured with


a pluggable strategy: the
MonitoringStrategy . By default, a polling
strategy is used, where the incoming folder is polled for new messages every five
minutes. This interval
can be changed by setting the pollingInterval property on the strategy.
By default, all
MonitoringStrategy implementations delete the handled
messages; this can be changed by setting the deleteMessages
property.

As an alternative to the polling approaches, which are quite inefficient, there is a monitoring strategy
that uses IMAP IDLE. The
IDLE command is an optional
expansion of the IMAP email protocol that allows the mail server to send new message updates to
the
MailMessageReceiver asynchronously. If you use a IMAP server that supports the
IDLE command, you can plug in the
ImapIdleMonitoringStrategy
into the monitoringStrategy property.
In addition to a supporting server, you will need to use
JavaMail version 1.4.1 or higher.

The following piece of configuration shows how to use the server-side email support, overiding the
default polling interval to a
value which checks every 30 seconds
(30.000 milliseconds):

<beans>

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

<bean id="messagingReceiver" class="org.springframework.ws.transport.mail.MailMessageReceiver">

<property name="messageFactory" ref="messageFactory"/>

<property name="from" value="Spring-WS SOAP Server &lt;[email protected]&gt;"/>

<property name="storeUri" value="imap://server:[email protected]/INBOX"/>

<property name="transportUri" value="smtp://smtp.example.com"/>

<property name="messageReceiver" ref="messageDispatcher"/>

<property name="monitoringStrategy">

<bean class="org.springframework.ws.transport.mail.monitor.PollingMonitoringStrategy">

<property name="pollingInterval" value="30000"/>

</bean>

</property>

</bean>

<bean id="messageDispatcher" class="org.springframework.ws.soap.server.SoapMessageDispatcher">

<property name="endpointMappings">

<bean

class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping
<property name="defaultEndpoint">

<bean class="com.example.MyEndpoint"/>

</property>

</bean>

</property>

</bean>

</beans>

5.3.5 Embedded HTTP Server transport

https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 29/71
09/03/2022 08:45 Spring Web Services Reference Documentation

Spring Web Services provides a transport based on Sun's JRE 1.6


HTTP server.
The embedded HTTP Server is a standalone
server that is simple to configure. It lends itself to a lighter
alternative to conventional servlet containers.

When using the embedded HTTP server, no external deployment descriptor is needed
( web.xml ).
You only need to define an
instance of the server and configure it to handle incoming requests.
The remoting module in the Core Spring Framework
contains a convenient factory bean for the HTTP server:
the SimpleHttpServerFactoryBean .
The most important property is
contexts, which maps context paths to corresponding
HttpHandler s.

Spring Web Services provides 2 implementations of the HttpHandler


interface: WsdlDefinitionHttpHandler
and
WebServiceMessageReceiverHttpHandler .
The former maps an incoming GET request to a WsdlDefinition .
The latter is
responsible for handling POST requests for web services messages and thus
needs a WebServiceMessageFactory (typically a
SaajSoapMessageFactory ) and a
WebServiceMessageReceiver (typically the
SoapMessageDispatcher ) to accomplish its
task.

To draw parallels with the servlet world, the contexts property plays
the role of servlet mappings in web.xml and the
WebServiceMessageReceiverHttpHandler is the equivalent of
a MessageDispatcherServlet .

The following snippet shows a simple configuration example of the HTTP server
transport:

<beans>

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

<bean id="messageReceiver" class="org.springframework.ws.soap.server.SoapMessageDispatcher">

<property name="endpointMappings" ref="endpointMapping"/>

</bean>

<bean id="endpointMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMeth


<property name="defaultEndpoint" ref="stockEndpoint"/>

</bean>

<bean id="httpServer" class="org.springframework.remoting.support.SimpleHttpServerFactoryBean">

<property name="contexts">

<map>

<entry key="/StockService.wsdl" value-ref="wsdlHandler"/>

<entry key="/StockService" value-ref="soapHandler"/>

</map>

</property>

</bean>

<bean id="soapHandler" class="org.springframework.ws.transport.http.WebServiceMessageReceiverHttpHandler">


<property name="messageFactory" ref="messageFactory"/>

<property name="messageReceiver" ref="messageReceiver"/>

</bean>

<bean id="wsdlHandler" class="org.springframework.ws.transport.http.WsdlDefinitionHttpHandler">

<property name="definition" ref="wsdlDefinition"/>

</bean>

</beans>

For more information on the SimpleHttpServerFactoryBean , refer to the


Javadoc.

5.3.6 XMPP transport
Finally, Spring Web Services 2.0 introduced support for XMPP, otherwise known as Jabber. The support
is based on the Smack
library.

Spring Web Services support for XMPP is very similar to the other transports: there is a a
XmppMessageSender for the
WebServiceTemplate and
and a XmppMessageReceiver to use with the
MessageDispatcher .

The following example shows how to set up the server-side XMPP components:

https://docs.spring.io/spring-ws/docs/2.4.0.RELEASE/reference/htmlsingle/ 30/71

You might also like