Adapters
Introduction
Channel Adapters are the components responsible for interacting with external systems or other components that
are external to the messaging system. As the name implies, the interaction consists of adapting the external
system or component to send-to and/or receive-from a MessageChannel. Within
Spring Integration, there is a distinction between source adapters and target
adapters. In the 1.0 Milestone 3 release, Spring Integration includes source and target adapters
for JMS, RMI, Files, Streams, Spring's HttpInvoker and Spring ApplicationEvents. A source adapter for FTP is
also available as well as target adapters for sending e-mail and invoking Web Services.
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:
JmsPollingSourceAdapter and JmsMessageDrivenSourceAdapter.
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 JmsPollingSourceAdapter 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 JmsPollingSourceAdapter also requires a 'channel' property that should be
a reference to a MessageChannel instance. The adapter accepts additional
properties such as: period, initialDelay, maxMessagesPerTask, and sendTimeout. The following example defines a
JMS source adapter that polls every 5 seconds and then sends to the "exampleChannel":
]]>
In most cases, Spring Integration's message-driven JMS adapter is more appropriate since it delegates to a
MessageListener container and supports dynamically adjusting concurrent
consumers. The JmsMessageDrivenSourceAdapter requires references to a
MessageChannel, a ConnectionFactory, and a
Destination (or 'destinationName'). The following example defines a JMS
message-driven source adapter that receives from the JMS queue called "exampleQueue" and then sends to
the Spring Integration channel named "exampleChannel":
]]>
For both source adapter types, Spring's MessageConverter strategy is used to
convert the JMS message into a plain Java object, and then Spring Integration's
MessageMapper strategy is used to convert from the plain object to a
Message.
The JmsTargetAdapter is a MessageHandler implementation
that 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 RmiSourceAdapter 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: RmiSourceAdapter rmiSourceAdapter = new RmiSourceAdapter(channel);
The RmiTargetAdapter encapsulates the creation of a proxy that is capable of
communicating with an RmiSourceAdapter 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
RmiSourceAdapter (the prefix is available as a constant).
String url = "http://somehost:1099/" + RmiSourceAdapter.SERVICE_NAME_PREFIX + "someChannel";
RmiTargetAdapter rmiTargetAdapter = new RmiTargetAdapter(url);
HttpInvoker Adapters
The source and target 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 HttpInvokerSourceAdapter 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 source
adapter. As with the RmiTargetAdapter, the
HttpInvokerTargetAdapter only requires the URL that matches an instance of
HttpInvokerSourceAdapter running in a web application.
File Adapters
The FileSourceAdapter extends the generic PollingSourceAdapter
(just as the polling JMS adapter does). It requires the following constructor arguments:
public FileSourceAdapter(File directory, MessageChannel channel, int period)
Optional properties include 'initialDelay' and 'maxMessagesPerTask'.
The FileTargetAdapter constructor only 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 FtpSourceAdapter. The adapter
expects a number of properties for connecting to the FTP server (as shown below) as well as the
'channel' and the 'period' for polling. For example, the following adapter would poll every 30 seconds:
]]>
Mail Adapters
Spring Integration currently provides support for outbound email only with the
MailTargetAdapter. 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 attributes in the MessageHeader with
the following constants defining the keys:
MailAttributeKeys.SUBJECT
MailAttributeKeys.TO
MailAttributeKeys.CC
MailAttributeKeys.BCC
MailAttributeKeys.FROM
MailAttributeKeys.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:
SimpleWebServiceTargetAdapter and
MarshallingWebServiceTargetAdapter. 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.simpleAdapter = new SimpleWebServiceTargetAdapter(uri);
marshallingAdapter = new MarshallingWebServiceTargetAdapter(uri, marshaller);
As with the other target adapters, this can then be referenced from a MessageEndpoint
that is subscribed to a channel. The endpoint is then responsible for passing the response to the proper
channel. It will first check for a returnAddress on the original message's header, and it
will fallback to the endpoint's own default output channel.
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 ByteStreamSourceAdapter and
CharacterStreamSourceAdapter extend the PolllingSourceAdapter so
that 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
ByteStreamSourceAdapter 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: ByteStreamTargetAdapter and
CharacterStreamTargetAdapter. 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 MessageHandler interface, they can be referenced from an
endpoint 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 ApplicationEventSourceAdapter (as with all source adapters, if a
MessageBus is defined, it will automatically detect the event source adapter). The
ApplicationEventSourceAdapter 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
ApplicationEventTargetAdapter class as the handler of an endpoint (such configuration
will be described in detail in ). This adapter implements Spring's
ApplicationEventPublisherAware interface and thus acts as a bridge between
Spring Integration Messages and ApplicationEvents.