Adapters
Introduction
Spring Integration provides a number of implementations of the MessageSource
and MessageTarget interfaces that serve as adapters for interacting with
external systems or components that are not part of the messaging system. These source and target
implementations can be configured within the same channel-adapter element that we
have already discussed. Essentially, the external system or component sends-to and/or receives-from a
MessageChannel. In the 1.0 Milestone 6 release, Spring Integration includes
source and target implementations for JMS, Files, FTP, Streams, and Spring ApplicationEvents.
Adapters that allow an external system to perform request-reply operations across Spring Integration
MessageChannels are actually examples of the Messaging Gateway
pattern. Therefore, those implementations are typically called "gateways" (whereas "source" and "target"
are in-only and out-only interactions respectively). For example, Spring Integration provides a
JmsSource that is polled by the bus-managed scheduler, but
also provides a JmsGateway. The gateway differs from the source in that it is an
event-driven consumer rather than a polling consumer,
and it is capable of waiting for reply messages. Spring Integration also provides gateways for RMI and
Spring's HttpInvoker.
Finally, adapters that enable interaction with external systems by invoking them for
request/reply interactions (the response is sent back on a Message Channel) are typically called
handlers in Spring Integration, since they implement the
MessageHandler interface. Basically, these types of adapters can be
configured exactly like any POJO with the <service-activator> element. Spring Integration provides
RMI, HttpInvoker, and Web Service handler implementations.
All of these adapters are discussed in this section. However, namespace support is provided for many of them
and is typically the most convenient option for configuration. For examples, see
.
JMS Adapters
Spring Integration provides two adapters for accepting JMS messages (as mentioned above):
JmsSource and JmsGateway. The former uses Spring's
JmsTemplate to receive based on a polling period. The latter configures and delegates to
an instance of Spring's DefaultMessageListenerContainer.
The JmsSource requires a reference to either a single JmsTemplate
instance or both ConnectionFactory and Destination
(a 'destinationName' can be provided in place of the 'destination' reference). The JmsSource
can then be referenced from a "channel-adapter" element that connects the source to a
MessageChannel instance. The following example defines a JMS source with
a JmsTemplate as a constructor-argument.
]]>
In most cases, Spring Integration's message-driven JmsGateway is more appropriate since it
delegates to a MessageListener container, supports dynamically adjusting
concurrent consumers, and can also handle replies. The JmsGateway requires references to
a ConnectionFactory, and a Destination (or
'destinationName'). The following example defines a JmsGateway that receives from the JMS
queue called "exampleQueue". Note that the 'expectReply' property has been set to 'true' (it is 'false' by
default):
]]>
The JmsTarget implements the MessageTarget interface
and is capable of mapping Spring Integration Messages to JMS messages and then
sending to a JMS destination. It requires either a 'jmsTemplate' reference or both 'connectionFactory' and
'destination' references (again, the 'destinationName' may be provided in place of the 'destination). In
, you will see how to configure a JMS target adapter with Spring
Integration's namespace support.
RMI Adapters
The RmiGateway is built upon Spring's RmiServiceExporter.
However, since it is adapting a MessageChannel, there is no need to specify
the serviceInterface. Likewise, the serviceName is automatically
generated based on the channel name. Therefore, creating the adapter is as simple as providing a reference
to its channel: RmiGateway rmiGateway = new RmiGateway(channel);
The RmiHandler encapsulates the creation of a proxy that is capable of
communicating with an RmiGateway running in another process. Since the interface
is already known, the only required information is the URL. The URL should include the host, port (default is
'1099'), and 'serviceName'. The 'serviceName' must match that created by the
RmiGateway (the prefix is available as a constant).
String url = "http://somehost:1099/" + RmiGateway.SERVICE_NAME_PREFIX + "someChannel";
RmiHandler rmiHandler = new RmiHandler(url);
HttpInvoker Adapters
The adapters for HttpInvoker are very similar to the RMI adapters. For a source, only the
channel needs to be provided, and for a target, only the URL. If running in a Spring MVC environment, then
the HttpInvokerGateway simply needs to be defined and provided in a
HandlerMapping. For example, the following would be exposed at the path
"http://somehost/path-mapped-to-dispatcher-servlet/httpInvokerAdapter" when a simple
BeanNameUrlHandlerMapping strategy is enabled:
]]>
When not running in a Spring MVC application, simply define a servlet in 'web.xml' whose type is
HttpRequestHandlerServlet and whose name matches the bean name of the gateway
adapter. As with the RmiHandler, the
HttpInvokerHandler only requires the URL that matches an instance of
HttpInvokerGateway running in a web application.
File Adapters
The FileSource requires the directory as a constructor argument:
public FileSource(File directory)
It can then be connected to a MessageChannel when referenced from
a "channel-adapter" element.
The FileTarget constructor also requires the 'directory' argument. The target
adapter also accepts an implementation of the FileNameGenerator strategy that
defines the following method: String generateFileName(Message message)
FTP Adapters
To poll a directory with FTP, configure an instance of FtpSource and then connect
it to a channel by configuring a channel-adapter. The FtpSource
expects a number of properties for connecting to the FTP server as shown below.
]]>
Mail Adapters
Spring Integration currently provides support for outbound email only with the
MailTarget. This adapter delegates to a configured instance of Spring's
JavaMailSender, and its various mapping strategies use Spring's
MailMessage abstraction. By default text-based mails are created when
the handled message has a String-based payload. If the message payload is a byte array, then that will
be mapped to an attachment.
The adapter also delegates to a MailHeaderGenerator for providing the
mail's properties, such as the recipients (TO, CC, and BCC), the from/reply-to, and the subject.
message);
}]]>
The default implementation will look for values in the MessageHeaders with
the following constants defining the header names:
MailHeaders.SUBJECT
MailHeaders.TO
MailHeaders.CC
MailHeaders.BCC
MailHeaders.FROM
MailHeaders.REPLY_TO
A static implementation is also available out-of-the-box and may be useful for testing. However, when
customizing, the properties would typically be generated dynamically based on the message itself. The
following is an example of a configured mail adapter.
]]>
Web Service Adapters
To invoke a Web Service upon sending a message to a channel, there are two options:
SimpleWebServiceHandler and
MarshallingWebServiceHandler. The former will accept either a
String or javax.xml.transform.Source as the message
payload. The latter provides support for any implementation of the Marshaller
and Unmarshaller interfaces. Both require the URI of the Web Service to be
called.simpleHandler = new SimpleWebServiceHandler(uri);
marshallingHandler = new MarshallingWebServiceHandler(uri, marshaller);
Either adapter can then be referenced from a service-activator element
that is subscribed to an input-channel. The endpoint is then responsible for passing the response to the
proper reply channel. It will first check for an "output-channel" on the service-activator and will
fallback to a RETURN_ADDRESS in the original message's headers.
For more detail on the inner workings, see the Spring Web Services reference guide's chapter covering
client access
as well as the chapter covering
Object/XML mapping.
Stream Adapters
Spring Integration also provides adapters for streams. Both ByteStreamSource and
CharacterStreamSource implement the PollableSource
interface. By configuring one of these within a channel-adapter element, the polling period can be configured,
and the Message Bus can automatically detect and schedule them. The byte stream version requires an
InputStream, and the character stream version requires a Reader as
the single constructor argument. The ByteStreamSource also accepts the 'bytesPerMessage'
property to determine how many bytes it will attempt to read into each Message.
For target streams, there are also two implementations: ByteStreamTarget and
CharacterStreamTarget. Each requires a single constructor argument -
OutputStream for byte streams or Writer for character streams,
and each provides a second constructor that adds the optional 'bufferSize' property. Since both of these
ultimately implement the MessageTarget interface, they can be referenced from a
channel-adapter configuration as will be described in more detail in
.
ApplicationEvent Adapters
Spring ApplicationEvents can also be integrated as either a source or target for Spring
Integration message channels. To receive the events and send to a channel, simply define an instance of Spring
Integration's ApplicationEventSource (as with all source implementations, this can then
be configured within a "channel-adapter" element and automatically detected by the message bus). The
ApplicationEventSource also implements Spring's ApplicationListener
interface. By default it will pass all received events as Spring Integration Messages. To limit based on the type
of event, configure the list of event types that you want to receive with the 'eventTypes' property.
To send Spring ApplicationEvents, register an instance of the
ApplicationEventTarget class as the 'target' of a Channel Adapter (such configuration will
be described in detail in ). This target also implements Spring's
ApplicationEventPublisherAware interface and thus acts as a bridge between
Spring Integration Messages and ApplicationEvents.