From 484583c2864b33b3d6f8a6377e390c79aa2019dd Mon Sep 17 00:00:00 2001 From: Nicolas Labrot Date: Sun, 20 Sep 2015 16:12:13 +0200 Subject: [PATCH] Add merged annotation support to @CrossOrigin Issue: SPR-13468 I have signed and agree to the terms of the SpringSource Individual Contributor License Agreement. --- .../RequestMappingHandlerMapping.java | 4 +- .../method/annotation/CrossOriginTests.java | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java index 2deead181c77..e2b52c61db9a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java @@ -286,8 +286,8 @@ protected String[] resolveEmbeddedValuesInPatterns(String[] patterns) { @Override protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mappingInfo) { HandlerMethod handlerMethod = createHandlerMethod(handler, method); - CrossOrigin typeAnnotation = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), CrossOrigin.class); - CrossOrigin methodAnnotation = AnnotationUtils.findAnnotation(method, CrossOrigin.class); + CrossOrigin typeAnnotation = AnnotatedElementUtils.findMergedAnnotation(handlerMethod.getBeanType(), CrossOrigin.class); + CrossOrigin methodAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, CrossOrigin.class); if (typeAnnotation == null && methodAnnotation == null) { return null; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/CrossOriginTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/CrossOriginTests.java index 690a743e6e57..d92ff34d5cb9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/CrossOriginTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/CrossOriginTests.java @@ -16,6 +16,11 @@ package org.springframework.web.servlet.mvc.method.annotation; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.lang.reflect.Method; import java.util.Arrays; @@ -180,6 +185,32 @@ public void classLevel() throws Exception { assertTrue(config.getAllowCredentials()); } + @Test // SPR-13468 + public void classLevelMetaAnnotation() throws Exception { + this.handlerMapping.registerHandler(new ClassLevelControllerWithMetaAnnotation()); + + this.request.setRequestURI("/foo"); + HandlerExecutionChain chain = this.handlerMapping.getHandler(request); + CorsConfiguration config = getCorsConfiguration(chain, false); + assertNotNull(config); + assertArrayEquals(new String[]{"GET"}, config.getAllowedMethods().toArray()); + assertArrayEquals(new String[]{"http://foo.com"}, config.getAllowedOrigins().toArray()); + assertTrue(config.getAllowCredentials()); + } + + @Test // SPR-13468 + public void methodLevelMetaAnnotation() throws Exception { + this.handlerMapping.registerHandler(new MethodLevelControllerWithMetaAnnotation()); + + this.request.setRequestURI("/foo"); + HandlerExecutionChain chain = this.handlerMapping.getHandler(request); + CorsConfiguration config = getCorsConfiguration(chain, false); + assertNotNull(config); + assertArrayEquals(new String[]{"GET"}, config.getAllowedMethods().toArray()); + assertArrayEquals(new String[]{"http://foo.com"}, config.getAllowedOrigins().toArray()); + assertTrue(config.getAllowCredentials()); + } + @Test public void preFlightRequest() throws Exception { this.handlerMapping.registerHandler(new MethodLevelController()); @@ -345,6 +376,34 @@ public void baz() { } + @Target({ElementType.METHOD, ElementType.TYPE}) + @Retention(RetentionPolicy.RUNTIME) + @Documented + @CrossOrigin + private @interface CrossOriginMetaAnnotation { + String[] origins() default {}; + String allowCredentials() default ""; + } + + @Controller + @CrossOriginMetaAnnotation(origins = "http://foo.com", allowCredentials = "true") + private static class ClassLevelControllerWithMetaAnnotation { + + @RequestMapping(path = "/foo", method = RequestMethod.GET) + public void foo() { + } + } + + + @Controller + private static class MethodLevelControllerWithMetaAnnotation { + + @RequestMapping(path = "/foo", method = RequestMethod.GET) + @CrossOriginMetaAnnotation(origins = "http://foo.com", allowCredentials = "true") + public void foo() { + } + } + private static class TestRequestMappingInfoHandlerMapping extends RequestMappingHandlerMapping { public void registerHandler(Object handler) {