30
30
import java .util .Map ;
31
31
import java .util .Optional ;
32
32
import java .util .Set ;
33
+ import java .util .concurrent .ConcurrentHashMap ;
33
34
import java .util .function .Function ;
34
35
import java .util .function .Predicate ;
35
36
@@ -355,6 +356,31 @@ private static void restoreAttributes(ServerRequest request, Map<String, Object>
355
356
request .attributes ().putAll (attributes );
356
357
}
357
358
359
+ private static Map <String , String > mergePathVariables (Map <String , String > oldVariables ,
360
+ Map <String , String > newVariables ) {
361
+
362
+ if (!newVariables .isEmpty ()) {
363
+ Map <String , String > mergedVariables = new LinkedHashMap <>(oldVariables );
364
+ mergedVariables .putAll (newVariables );
365
+ return mergedVariables ;
366
+ }
367
+ else {
368
+ return oldVariables ;
369
+ }
370
+ }
371
+
372
+ private static String mergePatterns (@ Nullable String oldPattern , String newPattern ) {
373
+ if (oldPattern != null ) {
374
+ if (oldPattern .endsWith ("/" ) && newPattern .startsWith ("/" )) {
375
+ oldPattern = oldPattern .substring (0 , oldPattern .length () - 1 );
376
+ }
377
+ return oldPattern + newPattern ;
378
+ }
379
+ else {
380
+ return newPattern ;
381
+ }
382
+
383
+ }
358
384
359
385
private static class HttpMethodPredicate implements RequestPredicate {
360
386
@@ -403,30 +429,33 @@ public PathPatternPredicate(PathPattern pattern) {
403
429
public boolean test (ServerRequest request ) {
404
430
PathContainer pathContainer = request .pathContainer ();
405
431
PathPattern .PathMatchInfo info = this .pattern .matchAndExtract (pathContainer );
406
- traceMatch ("Pattern" , this .pattern .getPatternString (), request .path (), info != null );
432
+ String patternString = this .pattern .getPatternString ();
433
+ traceMatch ("Pattern" , patternString , request .path (), info != null );
407
434
if (info != null ) {
408
- mergeTemplateVariables (request , info .getUriVariables ());
435
+ mergeAttributes (request , info .getUriVariables (), patternString );
409
436
return true ;
410
437
}
411
438
else {
412
439
return false ;
413
440
}
414
441
}
415
442
443
+ private static void mergeAttributes (ServerRequest request , Map <String , String > variables ,
444
+ String pattern ) {
445
+ Map <String , String > pathVariables = mergePathVariables (request .pathVariables (), variables );
446
+ request .attributes ().put (RouterFunctions .URI_TEMPLATE_VARIABLES_ATTRIBUTE ,
447
+ Collections .unmodifiableMap (pathVariables ));
448
+
449
+ pattern = mergePatterns (
450
+ (String ) request .attributes ().get (RouterFunctions .MATCHING_PATTERN_ATTRIBUTE ),
451
+ pattern );
452
+ request .attributes ().put (RouterFunctions .MATCHING_PATTERN_ATTRIBUTE , pattern );
453
+ }
454
+
416
455
@ Override
417
456
public Optional <ServerRequest > nest (ServerRequest request ) {
418
457
return Optional .ofNullable (this .pattern .matchStartOfPath (request .pathContainer ()))
419
- .map (info -> new SubPathServerRequestWrapper (request , info ));
420
- }
421
-
422
- private void mergeTemplateVariables (ServerRequest request , Map <String , String > variables ) {
423
- if (!variables .isEmpty ()) {
424
- Map <String , String > oldVariables = request .pathVariables ();
425
- Map <String , String > mergedVariables = new LinkedHashMap <>(oldVariables );
426
- mergedVariables .putAll (variables );
427
- request .attributes ().put (RouterFunctions .URI_TEMPLATE_VARIABLES_ATTRIBUTE ,
428
- Collections .unmodifiableMap (mergedVariables ));
429
- }
458
+ .map (info -> new SubPathServerRequestWrapper (request , info , this .pattern .getPatternString ()));
430
459
}
431
460
432
461
@ Override
@@ -601,23 +630,29 @@ private static class SubPathServerRequestWrapper implements ServerRequest {
601
630
602
631
private final ServerRequest request ;
603
632
604
- private final PathContainer subPathContainer ;
633
+ private final PathContainer pathContainer ;
605
634
606
- private final Map <String , String > pathVariables ;
635
+ private final Map <String , Object > attributes ;
607
636
608
- public SubPathServerRequestWrapper (ServerRequest request , PathPattern .PathRemainingMatchInfo info ) {
637
+ public SubPathServerRequestWrapper (ServerRequest request ,
638
+ PathPattern .PathRemainingMatchInfo info , String pattern ) {
609
639
this .request = request ;
610
- this .subPathContainer = new SubPathContainer (info .getPathRemaining ());
611
-
612
- this .pathVariables = mergePathVariables (request , info .getUriVariables ());
640
+ this .pathContainer = new SubPathContainer (info .getPathRemaining ());
641
+ this .attributes = mergeAttributes (request , info .getUriVariables (), pattern );
613
642
}
614
643
615
- private static Map <String , String > mergePathVariables (ServerRequest request ,
616
- Map <String , String > pathVariables ) {
644
+ private static Map <String , Object > mergeAttributes (ServerRequest request ,
645
+ Map <String , String > pathVariables , String pattern ) {
646
+ Map <String , Object > result = new ConcurrentHashMap <>(request .attributes ());
617
647
618
- Map <String , String > result = new LinkedHashMap <>(request .pathVariables ());
619
- result .putAll (pathVariables );
620
- return Collections .unmodifiableMap (result );
648
+ result .put (RouterFunctions .URI_TEMPLATE_VARIABLES_ATTRIBUTE ,
649
+ mergePathVariables (request .pathVariables (), pathVariables ));
650
+
651
+ pattern = mergePatterns (
652
+ (String ) request .attributes ().get (RouterFunctions .MATCHING_PATTERN_ATTRIBUTE ),
653
+ pattern );
654
+ result .put (RouterFunctions .MATCHING_PATTERN_ATTRIBUTE , pattern );
655
+ return result ;
621
656
}
622
657
623
658
@ Override
@@ -642,12 +677,12 @@ public UriBuilder uriBuilder() {
642
677
643
678
@ Override
644
679
public String path () {
645
- return this .subPathContainer .value ();
680
+ return this .pathContainer .value ();
646
681
}
647
682
648
683
@ Override
649
684
public PathContainer pathContainer () {
650
- return this .subPathContainer ;
685
+ return this .pathContainer ;
651
686
}
652
687
653
688
@ Override
@@ -700,14 +735,9 @@ public <T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> typeReference) {
700
735
return this .request .bodyToFlux (typeReference );
701
736
}
702
737
703
- @ Override
704
- public Optional <Object > attribute (String name ) {
705
- return this .request .attribute (name );
706
- }
707
-
708
738
@ Override
709
739
public Map <String , Object > attributes () {
710
- return this .request . attributes () ;
740
+ return this .attributes ;
711
741
}
712
742
713
743
@ Override
@@ -721,8 +751,11 @@ public MultiValueMap<String, String> queryParams() {
721
751
}
722
752
723
753
@ Override
754
+ @ SuppressWarnings ("unchecked" )
724
755
public Map <String , String > pathVariables () {
725
- return this .pathVariables ;
756
+ return (Map <String , String >) this .attributes .getOrDefault (
757
+ RouterFunctions .URI_TEMPLATE_VARIABLES_ATTRIBUTE , Collections .emptyMap ());
758
+
726
759
}
727
760
728
761
@ Override
0 commit comments