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
This commit is contained in:
Gary Russell
2019-10-16 10:33:09 -04:00
committed by Artem Bilan
parent 0d21823b16
commit 86f0ca2199
2 changed files with 16 additions and 6 deletions

View File

@@ -1267,9 +1267,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

@@ -170,6 +170,7 @@ public class MethodInvokingMessageProcessorTests {
this.name = fname + " " + lname;
}
@Override
public String toString() {
return "Person: " + this.name;
}
@@ -552,7 +553,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);
processor.setUseSpelInvoker(true);
optionalAndRequiredDottedWithAnnotatedMethodGuts(processor, false);
@@ -561,7 +563,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);
processor.setUseSpelInvoker(true);
DirectFieldAccessor compilerConfigAccessor = compileImmediate(processor);
@@ -577,17 +580,20 @@ public class MethodInvokingMessageProcessorTests {
processor.setBeanFactory(mock(BeanFactory.class));
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);
@@ -1380,8 +1386,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) {