16
16
17
17
package org .springframework .web .servlet .mvc .method .annotation ;
18
18
19
+ import java .lang .annotation .ElementType ;
20
+ import java .lang .annotation .Retention ;
21
+ import java .lang .annotation .RetentionPolicy ;
22
+ import java .lang .annotation .Target ;
19
23
import java .lang .reflect .Method ;
20
24
import java .util .Arrays ;
21
25
25
29
import org .junit .rules .ExpectedException ;
26
30
27
31
import org .springframework .beans .DirectFieldAccessor ;
32
+ import org .springframework .core .annotation .AnnotatedElementUtils ;
28
33
import org .springframework .core .annotation .AnnotationUtils ;
29
34
import org .springframework .http .HttpHeaders ;
30
35
import org .springframework .mock .web .test .MockHttpServletRequest ;
53
58
*
54
59
* @author Sebastien Deleuze
55
60
* @author Sam Brannen
61
+ * @author Nicolas Labrot
56
62
*/
57
63
public class CrossOriginTests {
58
64
@@ -79,17 +85,15 @@ public void noAnnotationWithoutOrigin() throws Exception {
79
85
this .handlerMapping .registerHandler (new MethodLevelController ());
80
86
MockHttpServletRequest request = new MockHttpServletRequest ("GET" , "/no" );
81
87
HandlerExecutionChain chain = this .handlerMapping .getHandler (request );
82
- CorsConfiguration config = getCorsConfiguration (chain , false );
83
- assertNull (config );
88
+ assertNull (getCorsConfiguration (chain , false ));
84
89
}
85
90
86
91
@ Test // SPR-12931
87
92
public void noAnnotationWithOrigin () throws Exception {
88
93
this .handlerMapping .registerHandler (new MethodLevelController ());
89
94
this .request .setRequestURI ("/no" );
90
95
HandlerExecutionChain chain = this .handlerMapping .getHandler (request );
91
- CorsConfiguration config = getCorsConfiguration (chain , false );
92
- assertNull (config );
96
+ assertNull (getCorsConfiguration (chain , false ));
93
97
}
94
98
95
99
@ Test // SPR-12931
@@ -98,8 +102,7 @@ public void noAnnotationPostWithOrigin() throws Exception {
98
102
this .request .setMethod ("POST" );
99
103
this .request .setRequestURI ("/no" );
100
104
HandlerExecutionChain chain = this .handlerMapping .getHandler (request );
101
- CorsConfiguration config = getCorsConfiguration (chain , false );
102
- assertNull (config );
105
+ assertNull (getCorsConfiguration (chain , false ));
103
106
}
104
107
105
108
@ Test
@@ -180,6 +183,32 @@ public void classLevel() throws Exception {
180
183
assertTrue (config .getAllowCredentials ());
181
184
}
182
185
186
+ @ Test // SPR-13468
187
+ public void classLevelComposedAnnotation () throws Exception {
188
+ this .handlerMapping .registerHandler (new ClassLevelMappingWithComposedAnnotation ());
189
+
190
+ this .request .setRequestURI ("/foo" );
191
+ HandlerExecutionChain chain = this .handlerMapping .getHandler (request );
192
+ CorsConfiguration config = getCorsConfiguration (chain , false );
193
+ assertNotNull (config );
194
+ assertArrayEquals (new String []{"GET" }, config .getAllowedMethods ().toArray ());
195
+ assertArrayEquals (new String []{"http://foo.com" }, config .getAllowedOrigins ().toArray ());
196
+ assertTrue (config .getAllowCredentials ());
197
+ }
198
+
199
+ @ Test // SPR-13468
200
+ public void methodLevelComposedAnnotation () throws Exception {
201
+ this .handlerMapping .registerHandler (new MethodLevelMappingWithComposedAnnotation ());
202
+
203
+ this .request .setRequestURI ("/foo" );
204
+ HandlerExecutionChain chain = this .handlerMapping .getHandler (request );
205
+ CorsConfiguration config = getCorsConfiguration (chain , false );
206
+ assertNotNull (config );
207
+ assertArrayEquals (new String []{"GET" }, config .getAllowedMethods ().toArray ());
208
+ assertArrayEquals (new String []{"http://foo.com" }, config .getAllowedOrigins ().toArray ());
209
+ assertTrue (config .getAllowCredentials ());
210
+ }
211
+
183
212
@ Test
184
213
public void preFlightRequest () throws Exception {
185
214
this .handlerMapping .registerHandler (new MethodLevelController ());
@@ -345,6 +374,33 @@ public void baz() {
345
374
346
375
}
347
376
377
+ @ Target ({ElementType .METHOD , ElementType .TYPE })
378
+ @ Retention (RetentionPolicy .RUNTIME )
379
+ @ CrossOrigin
380
+ private @interface ComposedCrossOrigin {
381
+ String [] origins () default {};
382
+ String allowCredentials () default "" ;
383
+ }
384
+
385
+ @ Controller
386
+ @ ComposedCrossOrigin (origins = "http://foo.com" , allowCredentials = "true" )
387
+ private static class ClassLevelMappingWithComposedAnnotation {
388
+
389
+ @ RequestMapping (path = "/foo" , method = RequestMethod .GET )
390
+ public void foo () {
391
+ }
392
+ }
393
+
394
+
395
+ @ Controller
396
+ private static class MethodLevelMappingWithComposedAnnotation {
397
+
398
+ @ RequestMapping (path = "/foo" , method = RequestMethod .GET )
399
+ @ ComposedCrossOrigin (origins = "http://foo.com" , allowCredentials = "true" )
400
+ public void foo () {
401
+ }
402
+ }
403
+
348
404
private static class TestRequestMappingInfoHandlerMapping extends RequestMappingHandlerMapping {
349
405
350
406
public void registerHandler (Object handler ) {
@@ -358,7 +414,7 @@ protected boolean isHandler(Class<?> beanType) {
358
414
359
415
@ Override
360
416
protected RequestMappingInfo getMappingForMethod (Method method , Class <?> handlerType ) {
361
- RequestMapping annotation = AnnotationUtils . findAnnotation (method , RequestMapping .class );
417
+ RequestMapping annotation = AnnotatedElementUtils . findMergedAnnotation (method , RequestMapping .class );
362
418
if (annotation != null ) {
363
419
return new RequestMappingInfo (
364
420
new PatternsRequestCondition (annotation .value (), getUrlPathHelper (), getPathMatcher (), true , true ),
0 commit comments