Skip to content

Commit f76397d

Browse files
authored
Support rewriting request parameters (#3669)
Introduced a method to modify or replace request parameters during request processing, providing greater flexibility for parameter handling in routing. Signed-off-by: raccoonback <[email protected]>
1 parent 7f638fb commit f76397d

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java

+25
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.springframework.web.servlet.function.ServerRequest;
4646
import org.springframework.web.util.UriComponentsBuilder;
4747
import org.springframework.web.util.UriTemplate;
48+
import org.springframework.web.util.UriUtils;
4849

4950
import static org.springframework.cloud.gateway.server.mvc.common.MvcUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR;
5051
import static org.springframework.util.CollectionUtils.unmodifiableMultiValueMap;
@@ -337,6 +338,30 @@ public static Function<ServerRequest, ServerRequest> rewritePath(String regexp,
337338
};
338339
}
339340

341+
public static Function<ServerRequest, ServerRequest> rewriteRequestParameter(String name, String replacement) {
342+
return request -> {
343+
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>(request.params());
344+
if (queryParams.containsKey(name)) {
345+
queryParams.remove(name);
346+
queryParams.add(name, replacement);
347+
}
348+
349+
MultiValueMap<String, String> encodedQueryParams = UriUtils.encodeQueryParams(queryParams);
350+
URI rewrittenUri = UriComponentsBuilder.fromUri(request.uri())
351+
.replaceQueryParams(unmodifiableMultiValueMap(encodedQueryParams))
352+
.build(true)
353+
.toUri();
354+
355+
return ServerRequest.from(request)
356+
.params(params -> {
357+
params.remove(name);
358+
params.add(name, replacement);
359+
})
360+
.uri(rewrittenUri)
361+
.build();
362+
};
363+
}
364+
340365
public static Function<ServerRequest, ServerRequest> routeId(String routeId) {
341366
return request -> {
342367
MvcUtils.setRouteId(request, routeId);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright 2013-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.gateway.server.mvc.filter;
18+
19+
import java.util.Collections;
20+
21+
import org.junit.jupiter.api.Test;
22+
23+
import org.springframework.mock.web.MockHttpServletRequest;
24+
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
25+
import org.springframework.web.servlet.function.ServerRequest;
26+
27+
import static org.assertj.core.api.Assertions.assertThat;
28+
29+
/**
30+
* @author raccoonback
31+
*/
32+
class BeforeFilterFunctionsTests {
33+
34+
@Test
35+
void rewriteRequestParameter() {
36+
MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path")
37+
.param("foo", "bar")
38+
.param("baz", "qux")
39+
.buildRequest(null);
40+
41+
ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList());
42+
43+
ServerRequest result = BeforeFilterFunctions.rewriteRequestParameter("foo", "replacement").apply(request);
44+
45+
assertThat(result.param("foo")).isPresent().hasValue("replacement");
46+
assertThat(result.uri().toString()).hasToString("http://localhost/path?baz=qux&foo=replacement");
47+
}
48+
49+
@Test
50+
void rewriteOnlyFirstRequestParameter() {
51+
MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path")
52+
.param("foo", "bar_1")
53+
.param("foo", "bar_2")
54+
.param("foo", "bar_3")
55+
.param("baz", "qux")
56+
.buildRequest(null);
57+
58+
ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList());
59+
60+
ServerRequest result = BeforeFilterFunctions.rewriteRequestParameter("foo", "replacement").apply(request);
61+
62+
assertThat(result.param("foo")).isPresent().hasValue("replacement");
63+
assertThat(result.uri().toString()).hasToString("http://localhost/path?baz=qux&foo=replacement");
64+
}
65+
66+
@Test
67+
void rewriteEncodedRequestParameter() {
68+
MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path")
69+
.param("foo[]", "bar")
70+
.param("baz", "qux")
71+
.buildRequest(null);
72+
73+
ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList());
74+
75+
ServerRequest result = BeforeFilterFunctions.rewriteRequestParameter("foo[]", "replacement[]").apply(request);
76+
77+
assertThat(result.param("foo[]")).isPresent().hasValue("replacement[]");
78+
assertThat(result.uri().toString()).hasToString("http://localhost/path?baz=qux&foo%5B%5D=replacement%5B%5D");
79+
}
80+
81+
@Test
82+
void rewriteRequestParameterWithEncodedRemainParameters() {
83+
MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path")
84+
.param("foo", "bar")
85+
.param("baz[]", "qux[]")
86+
.buildRequest(null);
87+
88+
ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList());
89+
90+
ServerRequest result = BeforeFilterFunctions.rewriteRequestParameter("foo", "replacement").apply(request);
91+
92+
assertThat(result.param("foo")).isPresent().hasValue("replacement");
93+
assertThat(result.uri().toString()).hasToString("http://localhost/path?baz%5B%5D=qux%5B%5D&foo=replacement");
94+
}
95+
96+
@Test
97+
void rewriteRequestParameterWithEncodedPath() {
98+
MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path/é/last")
99+
.param("foo", "bar")
100+
.buildRequest(null);
101+
102+
ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList());
103+
104+
ServerRequest result = BeforeFilterFunctions.rewriteRequestParameter("foo", "replacement").apply(request);
105+
106+
assertThat(result.param("foo")).isPresent().hasValue("replacement");
107+
assertThat(result.uri().toString()).hasToString("http://localhost/path/%C3%A9/last?foo=replacement");
108+
}
109+
110+
}

0 commit comments

Comments
 (0)