INT-4225: Add MessageConverters Infrastructure

JIRA: https://jira.spring.io/browse/INT-4225

* To allow flexible way to convert incoming messages for the target arguments in method invocation
add `ConfigurableCompositeMessageConverter` global bean under `ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME`
* Retrieve that bean for the `MessageHandlerMethodFactor` in the `MessagingMethodInvokerHelper` to enrich afterwards target `HandlerMethodArgumentResolver`s
* The `ContentTypeConversionTests` demonstrates conversion incoming JOSN `string` into the target POJO argument in the service method

*  Add `@Primary` support
* Add documentation about `@Primary` and `contentType` conversion

INT-1800: Add MTOM Support for WS

JIRA: https://jira.spring.io/browse/INT-1800

The Simple WebService Inbound and Outbound Gateways can operate with `WebServiceMessage`s directly.
This allows to create those messages manually and add attachments to them.
Or, on the other hand, process incoming messages with attachments manually.

For this purpose the `SimpleWebServiceOutboundGateway` is supplied with new `extractPayload` property.
Also the `UnmarshallingTransformer` can now process `MimeMessage` as payload to unmarshal it into object graph with attachments if that

INT-4225: Add MessageConverters infrastructure

JIRA: https://jira.spring.io/browse/INT-4225

* To allow flexible way to convert incoming messages for the target arguments in method invocation
add `ConfigurableCompositeMessageConverter` global bean under `ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME`
* Retrieve that bean for the `MessageHandlerMethodFactor` in the `MessagingMethodInvokerHelper` to enrich afterwards target `HandlerMethodArgumentResolver`s
* The `ContentTypeConversionTests` demonstrates conversion incoming JOSN `string` into the target POJO argument in the service method

*  Add `@Primary` support
* Add documentation about `@Primary` and `contentType` conversion

Doc Polishing

Change `@Primary` to `@Default`

Doc Polishing
This commit is contained in:
Artem Bilan
2017-03-01 17:51:54 -05:00
committed by Gary Russell
parent 5fe605470b
commit 28e8f23fd0
11 changed files with 436 additions and 21 deletions

View File

@@ -437,7 +437,7 @@ Throughout the reference manual, you will also see specific configuration and im
In the case of an Object, such a parameter will be mapped to a Message payload or part of the payload or header (when using the Spring Expression Language).
However there are times when the type of input parameter of the endpoint method does not match the type of the payload or its part.
In this scenario we need to perform type conversion.
Spring Integration provides a convenient way for registering type converters (using the Spring 3.x ConversionService) within its own instance of a conversion service bean named _integrationConversionService_.
Spring Integration provides a convenient way for registering type converters (using the Spring `ConversionService`) within its own instance of a conversion service bean named _integrationConversionService_.
That bean is automatically created as soon as the first converter is defined using the Spring Integration infrastructure.
To register a Converter all you need is to implement `org.springframework.core.convert.converter.Converter`, `org.springframework.core.convert.converter.GenericConverter` or `org.springframework.core.convert.converter.ConverterFactory`.
@@ -510,6 +510,38 @@ However, if you do want to use the Spring _conversionService_ as the Spring Inte
In this case the _conversionService_'s Converters will be available for Spring Integration runtime conversion.
=====
[[content-type-conversion]]
==== Content Type Conversion
Starting with _version 5.0_, by default, the method invocation mechanism is based on the `org.springframework.messaging.handler.invocation.InvocableHandlerMethod` infrastructure.
Its `HandlerMethodArgumentResolver` implementations (e.g. `PayloadArgumentResolver` and `MessageMethodArgumentResolver`) can use the `MessageConverter` abstraction to convert an incoming `payload` to the target method argument type.
The conversion can be based on the `contentType` message header.
For this purpose Spring Integration provides the `ConfigurableCompositeMessageConverter` that delegates to a list of registered converters to be invoked until one of them returns a non-null result.
By default this converter provides (in strict order):
* `MappingJackson2MessageConverter` if Jackson processor is present in classpath;
* `ByteArrayMessageConverter`
* `ObjectStringMessageConverter`
* `GenericMessageConverter`
Please, consult their JavaDocs for more information about their purpose and appropriate `contentType` value for conversion.
The `ConfigurableCompositeMessageConverter` is used because it can be be supplied with any other `MessageConverter` s including or excluding above mentioned default converters and registered as an appropriate bean in the application context overriding the default one:
[source,java]
----
@Bean(name = IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME)
public ConfigurableCompositeMessageConverter compositeMessageConverter() {
List<MessageConverter> converters =
Arrays.asList(new MarshallingMessageConverter(jaxb2Marshaller()),
new JavaSerializationMessageConverter());
return new ConfigurableCompositeMessageConverter(converters);
}
----
And those two new converters will be registered in the composite before the defaults.
You can also not use a `ConfigurableCompositeMessageConverter`, but provide your own `MessageConverter` by registering a bean with the name `integrationArgumentResolverMessageConverter` (`IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME` constant).
NOTE: The `MessageConverter`-based (including `contentType` header) conversion isn't available when using SpEL method invocation.
In this case, only regular class to class conversion mentioned above in the <<payload-type-conversion>> is available.
[[async-polling]]
==== Asynchronous polling

View File

@@ -18,7 +18,18 @@ To create a Service Activator, use the 'service-activator' element with the 'inp
<int:service-activator input-channel="exampleChannel" ref="exampleHandler"/>
----
The configuration above assumes that "exampleHandler" either contains a single method annotated with the @ServiceActivator annotation or that it contains only one public method at all.
The configuration above selects all methods from the `exampleHandler` which meet one of the Messaging requirements:
- annotated with `@ServiceActivator`;
- is `public`;
- not `void` return if `requiresReply == true`.
The target method for invocation at runtime is selected for each request message by their `payload` type.
Or as a fallback to `Message<?>` type if such a method is present on target class.
Starting with _version 5.0_, one service method can be marked with the `@org.springframework.integration.annotation.Default` as a fallback for all non-matching cases.
This can be useful when using <<content-type-conversion>> with the target method being invoked after conversion.
To delegate to an explicitly defined method of any object, simply add the "method" attribute.
[source,xml]

View File

@@ -104,7 +104,7 @@ With this sample:
* That `EvaluationContext` instance is injected into the `ExpressionEvaluatingTransformer` bean.
To provide a SpEL Function via Java Configuration you should declare a `SpelFunctionFactoryBean` bean for each function.
To provide a SpEL Function via Java Configuration, you should declare a `SpelFunctionFactoryBean` bean for each function.
The sample above can be configured as follows:
[source,java]
@@ -168,8 +168,8 @@ Instead of configuring the factory bean above, simply add one or more of these c
With this sample, two custom `PropertyAccessor` s will be injected to the `EvaluationContext` in the order that they are declared.
To provide `PropertyAccessor` s via Java Configuration you should declare `SpelPropertyAccessorRegistrar` bean with the `spelPropertyAccessorRegistrar` (the `IntegrationContextUtils.SPEL_PROPERTY_ACCESSOR_REGISTRAR_BEAN_NAME` constant) name.
The sample above can be configured like:
To provide `PropertyAccessor` s via Java Configuration, you should declare a `SpelPropertyAccessorRegistrar` bean with the name `spelPropertyAccessorRegistrar` (`IntegrationContextUtils.SPEL_PROPERTY_ACCESSOR_REGISTRAR_BEAN_NAME` constant).
The sample above can be configured as follows:
[source,java]
----

View File

@@ -19,6 +19,12 @@ See <<mongodb-outbound-gateway>> for more information.
The new `AsyncHttpRequestExecutingMessageHandler` adds support for `AsyncRestTemplate` for outbound channel adapter and gateway.
See <<AsyncHttpRequestExecutingMessageHandler>> for more information.
==== Content Type Conversion
Now that we use the new `InvocableHandlerMethod` -based infrastructure for service method invocations, we can perform `contentType` conversion from payload to target method argument.
See <<content-type-conversion>> for more information.
[[x5.0-general]]
=== General Changes
@@ -36,6 +42,9 @@ See <<tx-handle-message-advice>> for more information.
The `SmartLifecycleRoleController` now provides methods to obtain status of endpoints in roles.
See <<endpoint-roles>> for more information.
When targeting POJO objects as message handlers, one of the service methods can now be marked with the `@Default` annotation to provide a fallback mechanism for non-matched conditions.
See <<service-activator-namespace>> for more information.
==== JMS Changes
Previously, Spring Integration JMS XML configuration used a default bean name `connectionFactory` for the JMS Connection Factory, allowing the property to be omitted from component definitions.