Skip to content

Commit 053c86a

Browse files
authored
GH-3938: Fix HTTP XML configuration for ambiguity (#3939)
* GH-3938: Fix HTTP XML configuration for ambiguity Fixes #3938 The `encoding-mode` is a property of the `RestTemplate`. Therefore, it cannot be set on the component configuration together with an externally injected `rest-template` Even if `HttpRequestExecutingMessageHandler` has an assertion for such an ambiguity, the XML parser just ignores this `encoding-mode` when it encounters the `rest-template` * Fix `HttpAdapterParsingUtils.verifyNoRestTemplateAttributes()` to check for not allowed attributes with a `encoding-mode` as well * Remove a `default` from the `encoding-mode` to not cause an ambiguity in the parser * Fix some typos in the `spring-integration-http.xsd` * Rework `OutboundResponseTypeTests` to JUnit 5 **Cherry-pick to `5.5.x`** * * Fix error handling for `encoding-mode` in the `HttpAdapterParsingUtils` * Cover `encoding-mode` and `rest-template` ambiguity with a test against failing XML configuration * * Improve error message for ambiguous attributes in the `HttpAdapterParsingUtils`
1 parent 0d8e286 commit 053c86a

File tree

5 files changed

+89
-71
lines changed

5 files changed

+89
-71
lines changed

spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpAdapterParsingUtils.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,9 +36,10 @@
3636
* @author Gary Russell
3737
* @author Artem Bilan
3838
* @author Shiliang Li
39+
*
3940
* @since 2.0.2
4041
*/
41-
abstract class HttpAdapterParsingUtils {
42+
final class HttpAdapterParsingUtils {
4243

4344
static final String[] SYNC_REST_TEMPLATE_REFERENCE_ATTRIBUTES = {
4445
"request-factory", "error-handler", "message-converters"
@@ -48,14 +49,22 @@ static void verifyNoRestTemplateAttributes(Element element, ParserContext parser
4849
for (String attributeName : SYNC_REST_TEMPLATE_REFERENCE_ATTRIBUTES) {
4950
if (element.hasAttribute(attributeName)) {
5051
parserContext.getReaderContext().error("When providing a 'rest-template' reference, the '"
51-
+ attributeName + "' attribute is not allowed.",
52+
+ attributeName + "' attribute is not allowed, " +
53+
"it must be set on the provided template instead",
5254
parserContext.extractSource(element));
5355
}
5456
}
57+
58+
if (element.hasAttribute("encoding-mode")) {
59+
parserContext.getReaderContext().error("When providing a 'rest-template' reference, " +
60+
"the 'encoding-mode' must be set on the 'RestTemplate.uriTemplateHandler' property.",
61+
parserContext.extractSource(element));
62+
}
5563
}
5664

5765
static void configureUriVariableExpressions(BeanDefinitionBuilder builder, ParserContext parserContext,
5866
Element element) {
67+
5968
String uriVariablesExpression = element.getAttribute("uri-variables-expression");
6069

6170
List<Element> uriVariableElements = DomUtils.getChildElementsByTagName(element, "uri-variable");
@@ -73,7 +82,7 @@ static void configureUriVariableExpressions(BeanDefinitionBuilder builder, Parse
7382
}
7483

7584
if (hasUriVariableExpressions) {
76-
ManagedMap<String, Object> uriVariableExpressions = new ManagedMap<String, Object>();
85+
ManagedMap<String, Object> uriVariableExpressions = new ManagedMap<>();
7786
for (Element uriVariableElement : uriVariableElements) {
7887
String name = uriVariableElement.getAttribute("name");
7988
String expression = uriVariableElement.getAttribute("expression");
@@ -146,8 +155,8 @@ static void setExpectedResponseOrExpression(Element element, ParserContext parse
146155

147156
if (hasExpectedResponseType && hasExpectedResponseTypeExpression) {
148157
parserContext.getReaderContext()
149-
.error("The 'expected-response-type' and 'expected-response-type-expression' are mutually exclusive. " +
150-
"You can only have one or the other", element);
158+
.error("The 'expected-response-type' and 'expected-response-type-expression' " +
159+
"are mutually exclusive. You can only have one or the other", element);
151160
}
152161

153162
RootBeanDefinition expressionDef = null;
@@ -164,4 +173,7 @@ else if (hasExpectedResponseTypeExpression) {
164173
}
165174
}
166175

176+
private HttpAdapterParsingUtils() {
177+
}
178+
167179
}

spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http.xsd

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@
7373
By default 'status-code-expression' is null, meaning that the default '200 OK' response status
7474
will be returned.
7575
The 'http:inbound-gateway' resolves the 'status code' from the 'http_statusCode' header of the
76-
reply
77-
Message.
76+
reply Message.
7877
</xsd:documentation>
7978
</xsd:annotation>
8079
</xsd:attribute>
@@ -412,7 +411,7 @@
412411
<xsd:annotation>
413412
<xsd:documentation>
414413
Specify whether the outbound message's payload should be extracted
415-
when preparing the request body. Otherwise the Message instance itself
414+
when preparing the request body. Otherwise, the Message instance itself
416415
will be serialized.
417416
The default value is 'true'.
418417
</xsd:documentation>
@@ -484,7 +483,7 @@
484483
<xsd:annotation>
485484
<xsd:documentation>
486485
Specifies whether the outbound message's payload should be extracted
487-
when preparing the request body. Otherwise the Message instance itself
486+
when preparing the request body. Otherwise, the Message instance itself
488487
will be serialized.
489488
The default value is 'true'.
490489
</xsd:documentation>
@@ -493,8 +492,8 @@
493492
<xsd:attribute name="transfer-cookies" type="xsd:string" default="false">
494493
<xsd:annotation>
495494
<xsd:documentation><![CDATA[
496-
When set to "true", if a response contains a 'Set-Cookie' header, it will be mapped to a 'Cookie' header. This enables simple
497-
cookie handling where subsequent HTTP interactions in the same message flow can use a cookie
495+
When set to "true", if a response contains a 'Set-Cookie' header, it will be mapped to a 'Cookie' header.
496+
This enables simple cookie handling where subsequent HTTP interactions in the same message flow can use a cookie
498497
supplied by the server. Default is "false".
499498
]]></xsd:documentation>
500499
</xsd:annotation>
@@ -602,7 +601,8 @@
602601
<xsd:complexType name="headerType">
603602
<xsd:annotation>
604603
<xsd:documentation><![CDATA[
605-
Expression to be evaluated against the ServletRequest(makes BODY and Headers available) as well as URI Variables (e.g., foo/bar/{id}).
604+
Expression to be evaluated against the ServletRequest(makes BODY and Headers available)
605+
as well as URI Variables (e.g., foo/bar/{id}).
606606
]]></xsd:documentation>
607607
</xsd:annotation>
608608
<xsd:attribute name="name" use="required">
@@ -759,7 +759,7 @@
759759
<xsd:attribute name="allow-credentials" default="true">
760760
<xsd:annotation>
761761
<xsd:documentation>
762-
Set to "true" if the the browser should include any cookies associated to the domain
762+
Set to "true" if the browser should include any cookies associated to the domain
763763
of the request being annotated, or "false" if it should not. Empty string "" means undefined.
764764
If true, the pre-flight response will include the header
765765
'Access-Control-Allow-Credentials=true'. Default value is "true".
@@ -826,7 +826,7 @@
826826
<xsd:annotation>
827827
<xsd:documentation>
828828
Provide a reference to a list of HttpMessageConverter instances. If specified,
829-
these converters will replace all of the default converters that would normally
829+
these converters will replace all default converters that would normally
830830
be present on the underlying RestTemplate.
831831
</xsd:documentation>
832832
</xsd:annotation>
@@ -852,10 +852,11 @@
852852
]]></xsd:documentation>
853853
</xsd:annotation>
854854
</xsd:attribute>
855-
<xsd:attribute name="encoding-mode" default="TEMPLATE_AND_VALUES">
855+
<xsd:attribute name="encoding-mode">
856856
<xsd:annotation>
857857
<xsd:documentation>
858858
Set the encoding mode during URI building.
859+
Defaults to 'TEMPLATE_AND_VALUES'
859860
</xsd:documentation>
860861
</xsd:annotation>
861862
<xsd:simpleType>
@@ -948,7 +949,7 @@
948949
<xsd:attribute name="uri-variables-expression" type="xsd:string">
949950
<xsd:annotation>
950951
<xsd:documentation><![CDATA[
951-
Specifies the SpEL expression to be evaluate as a Map for URI variable placeholders within 'url'.
952+
Specifies the SpEL expression to be evaluated as a Map for URI variable placeholders within 'url'.
952953
This attribute is mutually exclusive with 'uri-variable' sub-elements.
953954
]]></xsd:documentation>
954955
</xsd:annotation>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans xmlns="http://www.springframework.org/schema/beans"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:int-http="http://www.springframework.org/schema/integration/http"
5+
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
6+
http://www.springframework.org/schema/integration/http https://www.springframework.org/schema/integration/http/spring-integration-http.xsd">
7+
8+
<bean id="restTemplate" class="org.mockito.Mockito" factory-method="mock">
9+
<constructor-arg value="org.springframework.web.client.RestTemplate"/>
10+
</bean>
11+
12+
<int-http:outbound-gateway url="/fake"
13+
rest-template="restTemplate"
14+
encoding-mode="NONE"/>
15+
16+
</beans>

spring-integration-http/src/test/java/org/springframework/integration/http/config/OutboundResponseTypeTests-context.xml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44
xmlns:int="http://www.springframework.org/schema/integration"
55
xmlns:int-http="http://www.springframework.org/schema/integration/http"
6-
xmlns:util="http://www.springframework.org/schema/util"
76
xsi:schemaLocation="http://www.springframework.org/schema/integration/http
87
https://www.springframework.org/schema/integration/http/spring-integration-http.xsd
98
http://www.springframework.org/schema/integration
109
https://www.springframework.org/schema/integration/spring-integration.xsd
1110
http://www.springframework.org/schema/beans
12-
https://www.springframework.org/schema/beans/spring-beans.xsd
13-
http://www.springframework.org/schema/util
14-
https://www.springframework.org/schema/util/spring-util.xsd">
11+
https://www.springframework.org/schema/beans/spring-beans.xsd">
1512

1613
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
1714

0 commit comments

Comments
 (0)