Skip to content

Commit d2472b4

Browse files
committed
Introduce queryParamPredicate in AbstractRequestLoggingFilter
Signed-off-by: Simone Conte <[email protected]>
1 parent 3819e2d commit d2472b4

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@
3131
import org.springframework.http.HttpHeaders;
3232
import org.springframework.http.server.ServletServerHttpRequest;
3333
import org.springframework.util.Assert;
34+
import org.springframework.util.LinkedMultiValueMap;
35+
import org.springframework.util.MultiValueMap;
3436
import org.springframework.util.StringUtils;
3537
import org.springframework.web.util.ContentCachingRequestWrapper;
38+
import org.springframework.web.util.UriComponentsBuilder;
3639
import org.springframework.web.util.WebUtils;
3740

3841
/**
@@ -99,6 +102,8 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter
99102

100103
private boolean includePayload = false;
101104

105+
private @Nullable Predicate<String> queryParamPredicate;
106+
102107
private @Nullable Predicate<String> headerPredicate;
103108

104109
private int maxPayloadLength = DEFAULT_MAX_PAYLOAD_LENGTH;
@@ -182,6 +187,30 @@ protected boolean isIncludePayload() {
182187
return this.includePayload;
183188
}
184189

190+
/**
191+
* Configure a predicate for selecting which query params should be logged if
192+
* {@link #setIncludeQueryString(boolean)} is set to {@code true}.
193+
* <p>By default this is not set in which case all query params are logged
194+
*
195+
* <p>If there are multiple values for the same query param,
196+
* the predicate will be applied once per query param name.
197+
* As a result, the use of this predicate may result in a different query string
198+
* than the one returned by {@link HttpServletRequest#getQueryString()}.
199+
* @param queryParamPredicate the predicate to use
200+
* @since 7.0
201+
*/
202+
public void setQueryParamPredicate(@Nullable Predicate<String> queryParamPredicate) {
203+
this.queryParamPredicate = queryParamPredicate;
204+
}
205+
206+
/**
207+
* The configured {@link #setQueryParamPredicate(Predicate) queryParamPredicate}.
208+
* @since 7.0
209+
*/
210+
protected @Nullable Predicate<String> getQueryParamPredicate() {
211+
return this.queryParamPredicate;
212+
}
213+
185214
/**
186215
* Configure a predicate for selecting which headers should be logged if
187216
* {@link #setIncludeHeaders(boolean)} is set to {@code true}.
@@ -326,6 +355,24 @@ protected String createMessage(HttpServletRequest request, String prefix, String
326355
if (isIncludeQueryString()) {
327356
String queryString = request.getQueryString();
328357
if (queryString != null) {
358+
if (getQueryParamPredicate() != null) {
359+
MultiValueMap<String, String> queryParams = UriComponentsBuilder.fromUriString("?" + queryString)
360+
.build()
361+
.getQueryParams();
362+
363+
MultiValueMap<String, String> updatedQueryParams = new LinkedMultiValueMap<>(queryParams);
364+
for (String name : queryParams.keySet()) {
365+
if (!getQueryParamPredicate().test(name)) {
366+
updatedQueryParams.set(name, "masked");
367+
break;
368+
}
369+
}
370+
371+
queryString = UriComponentsBuilder.newInstance()
372+
.queryParams(updatedQueryParams)
373+
.build()
374+
.getQuery();
375+
}
329376
msg.append('?').append(queryString);
330377
}
331378
}

spring-web/src/test/java/org/springframework/web/filter/RequestLoggingFilterTests.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,14 @@ void uri() throws Exception {
108108

109109
@Test
110110
void queryStringIncluded() throws Exception {
111-
request.setQueryString("booking=42");
111+
request.setQueryString("booking=42&code=73&category=hotel&code=37&category=resort");
112112
filter.setIncludeQueryString(true);
113+
filter.setQueryParamPredicate(name -> !name.equals("code") && !name.equals("ignore"));
113114

114115
applyFilter();
115116

116-
assertThat(filter.beforeRequestMessage).contains("/hotels?booking=42");
117-
assertThat(filter.afterRequestMessage).contains("/hotels?booking=42");
117+
assertThat(filter.beforeRequestMessage).contains("/hotels?booking=42&code=masked&category=hotel&category=resort");
118+
assertThat(filter.afterRequestMessage).contains("/hotels?booking=42&code=masked&category=hotel&category=resort");
118119
}
119120

120121
@Test

0 commit comments

Comments
 (0)