1
1
/*
2
- * Copyright 2002-2019 the original author or authors.
2
+ * Copyright 2002-2020 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
17
17
package org .springframework .web .servlet .mvc .method .annotation ;
18
18
19
- import java .awt .Color ;
19
+ import java .awt .*;
20
+ import java .lang .annotation .Documented ;
21
+ import java .lang .annotation .ElementType ;
22
+ import java .lang .annotation .Retention ;
23
+ import java .lang .annotation .RetentionPolicy ;
24
+ import java .lang .annotation .Target ;
20
25
import java .lang .reflect .Method ;
21
26
import java .net .URI ;
22
27
import java .security .Principal ;
70
75
import org .springframework .web .bind .support .ConfigurableWebBindingInitializer ;
71
76
import org .springframework .web .bind .support .SessionStatus ;
72
77
import org .springframework .web .bind .support .WebArgumentResolver ;
78
+ import org .springframework .web .bind .support .WebDataBinderFactory ;
73
79
import org .springframework .web .context .request .NativeWebRequest ;
74
80
import org .springframework .web .context .request .RequestContextHolder ;
75
81
import org .springframework .web .context .request .ServletWebRequest ;
76
82
import org .springframework .web .context .support .GenericWebApplicationContext ;
77
83
import org .springframework .web .method .HandlerMethod ;
78
84
import org .springframework .web .method .support .HandlerMethodArgumentResolver ;
79
85
import org .springframework .web .method .support .InvocableHandlerMethod ;
86
+ import org .springframework .web .method .support .ModelAndViewContainer ;
80
87
import org .springframework .web .servlet .HandlerMapping ;
81
88
import org .springframework .web .servlet .ModelAndView ;
82
89
import org .springframework .web .testfixture .servlet .MockHttpServletRequest ;
@@ -114,6 +121,7 @@ public void setup() throws Exception {
114
121
115
122
List <HandlerMethodArgumentResolver > customResolvers = new ArrayList <>();
116
123
customResolvers .add (new ServletWebArgumentResolverAdapter (new ColorArgumentResolver ()));
124
+ customResolvers .add (new CustomPrincipalArgumentResolver ());
117
125
118
126
GenericWebApplicationContext context = new GenericWebApplicationContext ();
119
127
context .refresh ();
@@ -145,7 +153,7 @@ public void handle() throws Exception {
145
153
Class <?>[] parameterTypes = new Class <?>[] {int .class , String .class , String .class , String .class , Map .class ,
146
154
Date .class , Map .class , String .class , String .class , TestBean .class , Errors .class , TestBean .class ,
147
155
Color .class , HttpServletRequest .class , HttpServletResponse .class , TestBean .class , TestBean .class ,
148
- User .class , OtherUser .class , Model .class , UriComponentsBuilder .class };
156
+ User .class , OtherUser .class , Principal . class , Model .class , UriComponentsBuilder .class };
149
157
150
158
String datePattern = "yyyy.MM.dd" ;
151
159
String formattedDate = "2011.03.16" ;
@@ -214,6 +222,7 @@ public void handle() throws Exception {
214
222
assertThat (model .get ("customArg" ) instanceof Color ).isTrue ();
215
223
assertThat (model .get ("user" ).getClass ()).isEqualTo (User .class );
216
224
assertThat (model .get ("otherUser" ).getClass ()).isEqualTo (OtherUser .class );
225
+ assertThat (((Principal ) model .get ("customUser" )).getName ()).isEqualTo ("Custom User" );
217
226
218
227
assertThat (model .get ("sessionAttribute" )).isSameAs (sessionAttribute );
219
228
assertThat (model .get ("requestAttribute" )).isSameAs (requestAttribute );
@@ -476,16 +485,24 @@ public String handle(
476
485
HttpServletResponse response ,
477
486
@ SessionAttribute TestBean sessionAttribute ,
478
487
@ RequestAttribute TestBean requestAttribute ,
479
- User user ,
488
+ @ Nullable User user , // gh-26117, gh-26117 (for @Nullable)
480
489
@ ModelAttribute OtherUser otherUser ,
490
+ @ AuthenticationPrincipal Principal customUser , // gh-25780
481
491
Model model ,
482
492
UriComponentsBuilder builder ) {
483
493
484
- model .addAttribute ("cookie" , cookieV ).addAttribute ("pathvar" , pathvarV ).addAttribute ("header" , headerV )
485
- .addAttribute ("systemHeader" , systemHeader ).addAttribute ("headerMap" , headerMap )
486
- .addAttribute ("dateParam" , dateParam ).addAttribute ("paramMap" , paramMap )
487
- .addAttribute ("paramByConvention" , paramByConvention ).addAttribute ("value" , value )
488
- .addAttribute ("customArg" , customArg ).addAttribute (user )
494
+ model .addAttribute ("cookie" , cookieV )
495
+ .addAttribute ("pathvar" , pathvarV )
496
+ .addAttribute ("header" , headerV )
497
+ .addAttribute ("systemHeader" , systemHeader )
498
+ .addAttribute ("headerMap" , headerMap )
499
+ .addAttribute ("dateParam" , dateParam )
500
+ .addAttribute ("paramMap" , paramMap )
501
+ .addAttribute ("paramByConvention" , paramByConvention )
502
+ .addAttribute ("value" , value )
503
+ .addAttribute ("customArg" , customArg )
504
+ .addAttribute (user )
505
+ .addAttribute ("customUser" , customUser )
489
506
.addAttribute ("sessionAttribute" , sessionAttribute )
490
507
.addAttribute ("requestAttribute" , requestAttribute )
491
508
.addAttribute ("url" , builder .path ("/path" ).build ().toUri ());
@@ -520,10 +537,15 @@ public String handleInInterface(
520
537
Model model ,
521
538
UriComponentsBuilder builder ) {
522
539
523
- model .addAttribute ("cookie" , cookieV ).addAttribute ("pathvar" , pathvarV ).addAttribute ("header" , headerV )
524
- .addAttribute ("systemHeader" , systemHeader ).addAttribute ("headerMap" , headerMap )
525
- .addAttribute ("dateParam" , dateParam ).addAttribute ("paramMap" , paramMap )
526
- .addAttribute ("paramByConvention" , paramByConvention ).addAttribute ("value" , value )
540
+ model .addAttribute ("cookie" , cookieV )
541
+ .addAttribute ("pathvar" , pathvarV )
542
+ .addAttribute ("header" , headerV )
543
+ .addAttribute ("systemHeader" , systemHeader )
544
+ .addAttribute ("headerMap" , headerMap )
545
+ .addAttribute ("dateParam" , dateParam )
546
+ .addAttribute ("paramMap" , paramMap )
547
+ .addAttribute ("paramByConvention" , paramByConvention )
548
+ .addAttribute ("value" , value )
527
549
.addAttribute ("customArg" , customArg ).addAttribute (user )
528
550
.addAttribute ("sessionAttribute" , sessionAttribute )
529
551
.addAttribute ("requestAttribute" , requestAttribute )
@@ -598,7 +620,6 @@ public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest
598
620
}
599
621
}
600
622
601
-
602
623
private static class User implements Principal {
603
624
604
625
@ Override
@@ -616,4 +637,26 @@ public String getName() {
616
637
}
617
638
}
618
639
640
+ private static class CustomPrincipalArgumentResolver implements HandlerMethodArgumentResolver {
641
+
642
+ @ Override
643
+ public boolean supportsParameter (MethodParameter parameter ) {
644
+ return (Principal .class .isAssignableFrom (parameter .getParameterType ()) &&
645
+ parameter .hasParameterAnnotation (AuthenticationPrincipal .class ));
646
+ }
647
+
648
+ @ Nullable
649
+ @ Override
650
+ public Object resolveArgument (
651
+ MethodParameter parameter , @ Nullable ModelAndViewContainer mavContainer ,
652
+ NativeWebRequest webRequest , @ Nullable WebDataBinderFactory binderFactory ) {
653
+
654
+ return (Principal ) () -> "Custom User" ;
655
+ }
656
+ }
657
+
658
+ @ Target ({ ElementType .PARAMETER , ElementType .ANNOTATION_TYPE })
659
+ @ Retention (RetentionPolicy .RUNTIME )
660
+ @ Documented
661
+ public @interface AuthenticationPrincipal {}
619
662
}
0 commit comments