Skip to content

Commit f62251a

Browse files
committed
Avoid pathVar-requestParam name collision
Closes gh-34499
1 parent f92f9c1 commit f62251a

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

Diff for: spring-web/src/main/java/org/springframework/web/service/invoker/HttpRequestValues.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ private String appendQueryParams(
493493

494494
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uriTemplate);
495495
for (Map.Entry<String, List<String>> entry : requestParams.entrySet()) {
496-
String nameVar = entry.getKey().replace(":", "%3A"); // suppress treatment as regex
496+
String nameVar = "queryParam-" + entry.getKey().replace(":", "%3A"); // suppress treatment as regex
497497
uriVars.put(nameVar, entry.getKey());
498498
for (int j = 0; j < entry.getValue().size(); j++) {
499499
String valueVar = nameVar + "[" + j + "]";

Diff for: spring-web/src/test/java/org/springframework/web/service/invoker/HttpRequestValuesTests.java

+13-11
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,19 @@ void queryParamsWithUriTemplate() {
7979

8080
assertThat(uriTemplate)
8181
.isEqualTo("/path?" +
82-
"{param1}={param1[0]}&" +
83-
"{param2}={param2[0]}&" +
84-
"{param2}={param2[1]}");
82+
"{queryParam-param1}={queryParam-param1[0]}&" +
83+
"{queryParam-param2}={queryParam-param2[0]}&" +
84+
"{queryParam-param2}={queryParam-param2[1]}");
8585

8686
assertThat(requestValues.getUriVariables())
87-
.containsOnlyKeys("param1", "param2", "param1[0]", "param2[0]", "param2[1]")
88-
.containsEntry("param1", "param1")
89-
.containsEntry("param2", "param2")
90-
.containsEntry("param1[0]", "1st value")
91-
.containsEntry("param2[0]", "2nd value A")
92-
.containsEntry("param2[1]", "2nd value B");
87+
.containsOnlyKeys(
88+
"queryParam-param1", "queryParam-param2", "queryParam-param1[0]",
89+
"queryParam-param2[0]", "queryParam-param2[1]")
90+
.containsEntry("queryParam-param1", "param1")
91+
.containsEntry("queryParam-param2", "param2")
92+
.containsEntry("queryParam-param1[0]", "1st value")
93+
.containsEntry("queryParam-param2[0]", "2nd value A")
94+
.containsEntry("queryParam-param2[1]", "2nd value B");
9395

9496
URI uri = UriComponentsBuilder.fromUriString(uriTemplate)
9597
.encode()
@@ -107,7 +109,7 @@ void queryParamWithSemicolon() {
107109
.build();
108110

109111
String uriTemplate = requestValues.getUriTemplate();
110-
assertThat(uriTemplate).isEqualTo("/path?{userId%3Aeq}={userId%3Aeq[0]}");
112+
assertThat(uriTemplate).isEqualTo("/path?{queryParam-userId%3Aeq}={queryParam-userId%3Aeq[0]}");
111113

112114
URI uri = UriComponentsBuilder.fromUriString(uriTemplate)
113115
.encode()
@@ -162,7 +164,7 @@ void requestPartAndRequestParam() {
162164
String uriTemplate = requestValues.getUriTemplate();
163165
assertThat(uriTemplate).isNotNull();
164166

165-
assertThat(uriTemplate).isEqualTo("/path?{query param}={query param[0]}");
167+
assertThat(uriTemplate).isEqualTo("/path?{queryParam-query param}={queryParam-query param[0]}");
166168

167169
URI uri = UriComponentsBuilder.fromUriString(uriTemplate)
168170
.encode()

Diff for: spring-web/src/test/java/org/springframework/web/service/invoker/PathVariableArgumentResolverTests.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 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.
@@ -16,11 +16,15 @@
1616

1717
package org.springframework.web.service.invoker;
1818

19+
import java.net.URI;
20+
1921
import org.junit.jupiter.api.Test;
2022

2123
import org.springframework.lang.Nullable;
2224
import org.springframework.web.bind.annotation.PathVariable;
25+
import org.springframework.web.bind.annotation.RequestParam;
2326
import org.springframework.web.service.annotation.GetExchange;
27+
import org.springframework.web.util.DefaultUriBuilderFactory;
2428

2529
import static org.assertj.core.api.Assertions.assertThat;
2630

@@ -46,6 +50,17 @@ void pathVariable() {
4650
assertPathVariable("id", "test");
4751
}
4852

53+
@Test // gh-34499
54+
void pathVariableAndRequestParamWithSameName() {
55+
this.service.executeWithPathVarAndRequestParam("{transfer-id}", "aValue");
56+
57+
assertPathVariable("transfer-id", "{transfer-id}");
58+
59+
HttpRequestValues values = this.client.getRequestValues();
60+
URI uri = (new DefaultUriBuilderFactory()).expand(values.getUriTemplate(), values.getUriVariables());
61+
assertThat(uri.toString()).isEqualTo("/transfers/%7Btransfer-id%7D?transfer-id=aValue");
62+
}
63+
4964
@SuppressWarnings("SameParameterValue")
5065
private void assertPathVariable(String name, @Nullable String expectedValue) {
5166
assertThat(this.client.getRequestValues().getUriVariables().get(name)).isEqualTo(expectedValue);
@@ -57,6 +72,11 @@ private interface Service {
5772
@GetExchange
5873
void execute(@PathVariable String id);
5974

75+
@GetExchange("/transfers/{transfer-id}")
76+
void executeWithPathVarAndRequestParam(
77+
@PathVariable("transfer-id") String transferId,
78+
@RequestParam("transfer-id") String transferIdParam);
79+
6080
}
6181

6282
}

0 commit comments

Comments
 (0)