26
26
import java .util .function .Function ;
27
27
import java .util .function .Predicate ;
28
28
29
+ import org .apache .commons .logging .Log ;
30
+ import org .apache .commons .logging .LogFactory ;
29
31
import reactor .core .publisher .Flux ;
30
32
import reactor .core .publisher .Mono ;
31
33
32
34
import org .springframework .http .HttpMethod ;
33
35
import org .springframework .http .MediaType ;
34
36
import org .springframework .http .server .reactive .ServerHttpRequest ;
35
37
import org .springframework .util .Assert ;
38
+ import org .springframework .util .StringUtils ;
36
39
import org .springframework .web .reactive .function .BodyExtractor ;
37
40
import org .springframework .web .server .WebSession ;
38
41
import org .springframework .web .util .UriUtils ;
48
51
*/
49
52
public abstract class RequestPredicates {
50
53
54
+ private static final Log logger = LogFactory .getLog (RequestPredicates .class );
55
+
51
56
private static final PathPatternParser DEFAULT_PATTERN_PARSER = new PathPatternParser ();
52
57
53
58
/**
@@ -119,11 +124,21 @@ public static RequestPredicate headers(Predicate<ServerRequest.Headers> headersP
119
124
public static RequestPredicate contentType (MediaType ... mediaTypes ) {
120
125
Assert .notEmpty (mediaTypes , "'mediaTypes' must not be empty" );
121
126
Set <MediaType > mediaTypeSet = new HashSet <>(Arrays .asList (mediaTypes ));
122
- return headers (headers -> {
123
- MediaType contentType = headers .contentType ().orElse (MediaType .APPLICATION_OCTET_STREAM );
124
- return mediaTypeSet .stream ()
125
- .anyMatch (mediaType -> mediaType .includes (contentType ));
127
+ return headers (new Predicate <ServerRequest .Headers >() {
128
+ @ Override
129
+ public boolean test (ServerRequest .Headers headers ) {
130
+ MediaType contentType =
131
+ headers .contentType ().orElse (MediaType .APPLICATION_OCTET_STREAM );
132
+ boolean match = mediaTypeSet .stream ()
133
+ .anyMatch (mediaType -> mediaType .includes (contentType ));
134
+ traceMatch ("Content-Type" , mediaTypeSet , contentType , match );
135
+ return match ;
136
+ }
126
137
138
+ @ Override
139
+ public String toString () {
140
+ return String .format ("Content-Type: %s" , mediaTypeSet );
141
+ }
127
142
});
128
143
}
129
144
@@ -138,12 +153,23 @@ public static RequestPredicate contentType(MediaType... mediaTypes) {
138
153
public static RequestPredicate accept (MediaType ... mediaTypes ) {
139
154
Assert .notEmpty (mediaTypes , "'mediaTypes' must not be empty" );
140
155
Set <MediaType > mediaTypeSet = new HashSet <>(Arrays .asList (mediaTypes ));
141
- return headers (headers -> {
142
- List <MediaType > acceptedMediaTypes = headers .accept ();
143
- MediaType .sortBySpecificityAndQuality (acceptedMediaTypes );
144
- return acceptedMediaTypes .stream ()
145
- .anyMatch (acceptedMediaType -> mediaTypeSet .stream ()
146
- .anyMatch (acceptedMediaType ::isCompatibleWith ));
156
+ return headers (new Predicate <ServerRequest .Headers >() {
157
+ @ Override
158
+ public boolean test (ServerRequest .Headers headers ) {
159
+ List <MediaType > acceptedMediaTypes = headers .accept ();
160
+ MediaType .sortBySpecificityAndQuality (acceptedMediaTypes );
161
+ boolean match = acceptedMediaTypes .stream ()
162
+ .anyMatch (acceptedMediaType -> mediaTypeSet .stream ()
163
+ .anyMatch (acceptedMediaType ::isCompatibleWith ));
164
+ traceMatch ("Accept" , mediaTypeSet , acceptedMediaTypes , match );
165
+ return match ;
166
+ }
167
+
168
+ @ Override
169
+ public String toString () {
170
+ return String .format ("Accept: %s" , mediaTypeSet );
171
+ }
172
+
147
173
});
148
174
}
149
175
@@ -238,7 +264,11 @@ public static RequestPredicate OPTIONS(String pattern) {
238
264
*/
239
265
public static RequestPredicate pathExtension (String extension ) {
240
266
Assert .notNull (extension , "'extension' must not be null" );
241
- return pathExtension (extension ::equalsIgnoreCase );
267
+ return pathExtension (pathExtension -> {
268
+ boolean match = extension .equalsIgnoreCase (pathExtension );
269
+ traceMatch ("Extension" , extension , pathExtension , match );
270
+ return match ;
271
+ });
242
272
}
243
273
244
274
/**
@@ -289,6 +319,14 @@ public static RequestPredicate queryParam(String name, Predicate<String> predica
289
319
};
290
320
}
291
321
322
+ private static void traceMatch (String prefix , Object desired , Object actual , boolean match ) {
323
+ if (logger .isTraceEnabled ()) {
324
+ String message = String .format ("%s \" %s\" %s against value \" %s\" " ,
325
+ prefix , desired , match ? "matches" : "does not match" , actual );
326
+ logger .trace (message );
327
+ }
328
+ }
329
+
292
330
293
331
private static class HttpMethodPredicate implements RequestPredicate {
294
332
@@ -301,7 +339,14 @@ public HttpMethodPredicate(HttpMethod httpMethod) {
301
339
302
340
@ Override
303
341
public boolean test (ServerRequest request ) {
304
- return this .httpMethod == request .method ();
342
+ boolean match = this .httpMethod == request .method ();
343
+ traceMatch ("Method" , this .httpMethod , request .method (), match );
344
+ return match ;
345
+ }
346
+
347
+ @ Override
348
+ public String toString () {
349
+ return this .httpMethod .toString ();
305
350
}
306
351
}
307
352
@@ -317,12 +362,11 @@ public PathPatternPredicate(PathPattern pattern) {
317
362
@ Override
318
363
public boolean test (ServerRequest request ) {
319
364
String path = request .path ();
320
- if (this .pattern .matches (path )) {
321
- if (request instanceof DefaultServerRequest ) {
322
- DefaultServerRequest defaultRequest = (DefaultServerRequest ) request ;
323
- Map <String , String > uriTemplateVariables = this .pattern .matchAndExtract (path );
324
- defaultRequest .exchange ().getAttributes ().put (RouterFunctions .URI_TEMPLATE_VARIABLES_ATTRIBUTE , uriTemplateVariables );
325
- }
365
+ boolean match = this .pattern .matches (path );
366
+ traceMatch ("Pattern" , this .pattern .getPatternString (), path , match );
367
+ if (match ) {
368
+ Map <String , String > uriTemplateVariables = this .pattern .matchAndExtract (path );
369
+ request .attributes ().put (RouterFunctions .URI_TEMPLATE_VARIABLES_ATTRIBUTE , uriTemplateVariables );
326
370
return true ;
327
371
}
328
372
else {
@@ -331,11 +375,19 @@ public boolean test(ServerRequest request) {
331
375
}
332
376
333
377
@ Override
334
- public ServerRequest subRequest (ServerRequest request ) {
378
+ public ServerRequest nestRequest (ServerRequest request ) {
335
379
String requestPath = request .path ();
336
380
String subPath = this .pattern .extractPathWithinPattern (requestPath );
381
+ if (!subPath .startsWith ("/" )) {
382
+ subPath = "/" + subPath ;
383
+ }
337
384
return new SubPathServerRequestWrapper (request , subPath );
338
385
}
386
+
387
+ @ Override
388
+ public String toString () {
389
+ return this .pattern .getPatternString ();
390
+ }
339
391
}
340
392
341
393
private static class HeadersPredicate implements RequestPredicate {
@@ -351,6 +403,11 @@ public HeadersPredicate(Predicate<ServerRequest.Headers> headersPredicate) {
351
403
public boolean test (ServerRequest request ) {
352
404
return this .headersPredicate .test (request .headers ());
353
405
}
406
+
407
+ @ Override
408
+ public String toString () {
409
+ return this .headersPredicate .toString ();
410
+ }
354
411
}
355
412
356
413
private static class SubPathServerRequestWrapper implements ServerRequest {
@@ -409,6 +466,11 @@ public <T> Optional<T> attribute(String name) {
409
466
return this .request .attribute (name );
410
467
}
411
468
469
+ @ Override
470
+ public Map <String , Object > attributes () {
471
+ return this .request .attributes ();
472
+ }
473
+
412
474
@ Override
413
475
public Optional <String > queryParam (String name ) {
414
476
return this .request .queryParam (name );
@@ -433,5 +495,11 @@ public Map<String, String> pathVariables() {
433
495
public Mono <WebSession > session () {
434
496
return this .request .session ();
435
497
}
498
+
499
+ @ Override
500
+ public String toString () {
501
+ return String .format ("%s %s" , method (), path ());
502
+ }
503
+
436
504
}
437
505
}
0 commit comments