From 9c24e161c1bb61190b54996883f5cca5163aec00 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Wed, 16 Oct 2019 10:33:09 -0400 Subject: [PATCH] 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 --- .../util/MessagingMethodInvokerHelper.java | 4 ++++ .../MethodInvokingMessageProcessorTests.java | 17 +++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java b/spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java index 3676fd9384..8260ef16b7 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java @@ -830,9 +830,13 @@ public class MessagingMethodInvokerHelper 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]; diff --git a/spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java index 2aeea845a6..04e198b42b 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java @@ -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 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) {