GH-3083: Support @Header with dotted literals

Fixes https://github.com/spring-projects/spring-integration/issues/3083

`@Header("foo.bar")` means extract property `bar` from header `foo`.

Support `@Header("'foo.bar'")`, meaning get the value of header `foo.bar`.

**cherry-pick to 5.1.x, 4.3.x**

# Conflicts:
#	spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java

# Conflicts:
#	spring-integration-core/src/main/java/org/springframework/integration/handler/support/MessagingMethodInvokerHelper.java
#	spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java
This commit is contained in:
Gary Russell
2019-10-16 10:33:09 -04:00
committed by Artem Bilan
parent a63f197d9b
commit 9c24e161c1
2 changed files with 15 additions and 6 deletions

View File

@@ -830,9 +830,13 @@ public class MessagingMethodInvokerHelper<T> extends AbstractExpressionEvaluator
AnnotationAttributes annotationAttributes =
(AnnotationAttributes) AnnotationUtils.getAnnotationAttributes(headerAnnotation);
String valueAttribute = annotationAttributes.getString(AnnotationUtils.VALUE);
int len = valueAttribute == null ? 0 : valueAttribute.length();
if (!StringUtils.hasText(valueAttribute)) {
headerName = methodParameter.getParameterName();
}
else if (len > 2 && valueAttribute.charAt(0) == '\'' && valueAttribute.charAt(len - 1) == '\'') {
headerName = valueAttribute.substring(1, len - 1);
}
else if (valueAttribute.indexOf('.') != -1) {
String[] tokens = valueAttribute.split("\\.", 2);
headerName = tokens[0];

View File

@@ -411,7 +411,8 @@ public class MethodInvokingMessageProcessorTests {
@Test
public void optionalAndRequiredDottedWithAnnotatedMethod() throws Exception {
AnnotatedTestService service = new AnnotatedTestService();
Method method = service.getClass().getMethod("optionalAndRequiredDottedHeader", String.class, Integer.class);
Method method = service.getClass().getMethod("optionalAndRequiredDottedHeader", String.class, Integer.class,
String.class);
MethodInvokingMessageProcessor processor = new MethodInvokingMessageProcessor(service, method);
optionalAndRequiredDottedWithAnnotatedMethodGuts(processor, false);
}
@@ -419,7 +420,8 @@ public class MethodInvokingMessageProcessorTests {
@Test
public void compiledOptionalAndRequiredDottedWithAnnotatedMethod() throws Exception {
AnnotatedTestService service = new AnnotatedTestService();
Method method = service.getClass().getMethod("optionalAndRequiredDottedHeader", String.class, Integer.class);
Method method = service.getClass().getMethod("optionalAndRequiredDottedHeader", String.class, Integer.class,
String.class);
MethodInvokingMessageProcessor processor = new MethodInvokingMessageProcessor(service, method);
DirectFieldAccessor compilerConfigAccessor = compileImmediate(processor);
optionalAndRequiredDottedWithAnnotatedMethodGuts(processor, true);
@@ -432,17 +434,20 @@ public class MethodInvokingMessageProcessorTests {
boolean compiled) {
Message<String> message = MessageBuilder.withPayload("hello")
.setHeader("dot2", new DotBean())
.setHeader("dotted.literal", "dotted")
.build();
Object result = processor.processMessage(message);
assertEquals("null42", result);
assertEquals("null42dotted", result);
message = MessageBuilder.withPayload("hello")
.setHeader("dot1", new DotBean())
.setHeader("dot2", new DotBean())
.setHeader("dotted.literal", "dotted")
.build();
result = processor.processMessage(message);
assertEquals("bar42", result);
assertEquals("bar42dotted", result);
message = MessageBuilder.withPayload("hello")
.setHeader("dot1", new DotBean())
.setHeader("dotted.literal", "dotted")
.build();
try {
result = processor.processMessage(message);
@@ -794,8 +799,8 @@ public class MethodInvokingMessageProcessorTests {
}
public String optionalAndRequiredDottedHeader(@Header(name = "dot1.foo", required = false) String prop,
@Header(name = "dot2.baz") Integer num) {
return prop + num;
@Header(name = "dot2.baz") Integer num, @Header("'dotted.literal'") String dotted) {
return prop + num + dotted;
}
public Properties propertiesMethod(Properties properties) {