INT-4523: Add DSL convert(Class<> cls) operator (#2556)
* INT-4523: Add DSL `convert(Class<> cls)` operator JIRA: https://jira.spring.io/browse/INT-4523 * Change the `LambdaMessageProcessor` to rely on the `MessageConverter` populated by the `IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME` This way all the Lambda-based handlers are going to work the same way as POJO-based via `MessagingMethodInvokerHelper` * Add `convert(Class<P> payloadType)` EIP-operator to perform similar to POJO-based method invocation argument conversion * * Fix `LambdaMessageProcessorTests` to inject a `ConfigurableCompositeMessageConverter` from the mocked `BeanFactory` * Make a `mappingJackson2MessageConverter.setStrictContentTypeMatch(true)` * Also obtain an `ObjectMapper` from the `Jackson2JsonObjectMapper` which is configured with the scanned possible Jackson modules. in the `ConfigurableCompositeMessageConverter` do not try to convert all the potential content without an appropriate JSON content-type header
This commit is contained in:
committed by
Gary Russell
parent
5bfd6971db
commit
54094da76b
@@ -587,6 +587,21 @@ public abstract class IntegrationFlowDefinition<B extends IntegrationFlowDefinit
|
||||
.transform(new MethodInvokingTransformer(processor), endpointConfigurer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the {@link MessageTransformingHandler} instance
|
||||
* for the provided {@code payloadType} to convert at runtime.
|
||||
* @param payloadType the {@link Class} for expected payload type.
|
||||
* @param <P> the payload type - 'convert to'.
|
||||
* @return the current {@link IntegrationFlowDefinition}.
|
||||
* @since 5.1
|
||||
* @see MethodInvokingTransformer
|
||||
* @see LambdaMessageProcessor
|
||||
*/
|
||||
public <P> B convert(Class<P> payloadType) {
|
||||
return transform(payloadType, p -> p);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Populate the {@link MessageTransformingHandler} instance for the provided {@link GenericTransformer}
|
||||
* for the specific {@code payloadType} to convert at runtime.
|
||||
@@ -599,7 +614,7 @@ public abstract class IntegrationFlowDefinition<B extends IntegrationFlowDefinit
|
||||
* @see LambdaMessageProcessor
|
||||
*/
|
||||
public <P, T> B transform(Class<P> payloadType, GenericTransformer<P, T> genericTransformer) {
|
||||
return this.transform(payloadType, genericTransformer, null);
|
||||
return transform(payloadType, genericTransformer, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -619,6 +634,25 @@ public abstract class IntegrationFlowDefinition<B extends IntegrationFlowDefinit
|
||||
return this.transform(null, genericTransformer, endpointConfigurer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the {@link MessageTransformingHandler} instance
|
||||
* for the provided {@code payloadType} to convert at runtime.
|
||||
* In addition accept options for the integration endpoint using {@link GenericEndpointSpec}.
|
||||
* @param payloadType the {@link Class} for expected payload type.
|
||||
* @param endpointConfigurer the {@link Consumer} to provide integration endpoint options.
|
||||
* @param <P> the payload type - 'transform to'.
|
||||
* @return the current {@link IntegrationFlowDefinition}.
|
||||
* @since 5.1
|
||||
* @see MethodInvokingTransformer
|
||||
* @see LambdaMessageProcessor
|
||||
* @see GenericEndpointSpec
|
||||
*/
|
||||
public <P> B convert(Class<P> payloadType,
|
||||
Consumer<GenericEndpointSpec<MessageTransformingHandler>> endpointConfigurer) {
|
||||
|
||||
return transform(payloadType, p -> p, endpointConfigurer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the {@link MessageTransformingHandler} instance for the provided {@link GenericTransformer}
|
||||
* for the specific {@code payloadType} to convert at runtime.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2016-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,12 +25,10 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.integration.support.utils.IntegrationUtils;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
@@ -48,11 +46,11 @@ public class LambdaMessageProcessor implements MessageProcessor<Object>, BeanFac
|
||||
|
||||
private final Method method;
|
||||
|
||||
private final TypeDescriptor payloadType;
|
||||
private final Class<?> payloadType;
|
||||
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
private ConversionService conversionService;
|
||||
private MessageConverter messageConverter;
|
||||
|
||||
public LambdaMessageProcessor(Object target, Class<?> payloadType) {
|
||||
Assert.notNull(target, "'target' must not be null");
|
||||
@@ -79,16 +77,14 @@ public class LambdaMessageProcessor implements MessageProcessor<Object>, BeanFac
|
||||
this.method = methodValue.get();
|
||||
this.method.setAccessible(true);
|
||||
this.parameterTypes = this.method.getParameterTypes();
|
||||
this.payloadType = payloadType != null ? TypeDescriptor.valueOf(payloadType) : null;
|
||||
this.payloadType = payloadType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
ConversionService conversionService = IntegrationUtils.getConversionService(beanFactory);
|
||||
if (conversionService == null) {
|
||||
conversionService = DefaultConversionService.getSharedInstance();
|
||||
}
|
||||
this.conversionService = conversionService;
|
||||
this.messageConverter =
|
||||
beanFactory.getBean(IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME,
|
||||
MessageConverter.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,14 +105,12 @@ public class LambdaMessageProcessor implements MessageProcessor<Object>, BeanFac
|
||||
}
|
||||
else {
|
||||
if (this.payloadType != null) {
|
||||
if (Message.class.isAssignableFrom(this.payloadType.getType())) {
|
||||
if (Message.class.isAssignableFrom(this.payloadType)) {
|
||||
args[i] = message;
|
||||
}
|
||||
else {
|
||||
args[i] = this.conversionService.convert(message.getPayload(),
|
||||
TypeDescriptor.forObject(message.getPayload()), this.payloadType);
|
||||
args[i] = this.messageConverter.fromMessage(message, this.payloadType);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
args[i] = message.getPayload();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
* Copyright 2017-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.integration.support.json.Jackson2JsonObjectMapper;
|
||||
import org.springframework.integration.support.json.JacksonPresent;
|
||||
import org.springframework.messaging.converter.ByteArrayMessageConverter;
|
||||
import org.springframework.messaging.converter.CompositeMessageConverter;
|
||||
@@ -78,7 +79,10 @@ public class ConfigurableCompositeMessageConverter extends CompositeMessageConve
|
||||
List<MessageConverter> converters = new LinkedList<>();
|
||||
|
||||
if (JacksonPresent.isJackson2Present()) {
|
||||
converters.add(new MappingJackson2MessageConverter());
|
||||
MappingJackson2MessageConverter mappingJackson2MessageConverter = new MappingJackson2MessageConverter();
|
||||
mappingJackson2MessageConverter.setStrictContentTypeMatch(true);
|
||||
mappingJackson2MessageConverter.setObjectMapper(new Jackson2JsonObjectMapper().getObjectMapper());
|
||||
converters.add(mappingJackson2MessageConverter);
|
||||
}
|
||||
converters.add(new ByteArrayMessageConverter());
|
||||
converters.add(new ObjectStringMessageConverter());
|
||||
|
||||
Reference in New Issue
Block a user