|
16 | 16 |
|
17 | 17 | package org.springframework.web.servlet.mvc.method.annotation; |
18 | 18 |
|
| 19 | +import java.lang.reflect.AnnotatedElement; |
19 | 20 | import java.lang.reflect.Method; |
20 | 21 | import java.util.ArrayList; |
21 | 22 | import java.util.List; |
22 | 23 |
|
23 | 24 | import org.springframework.context.EmbeddedValueResolverAware; |
| 25 | +import org.springframework.core.annotation.AnnotatedElementUtils; |
| 26 | +import org.springframework.core.annotation.AnnotationAttributes; |
24 | 27 | import org.springframework.core.annotation.AnnotationUtils; |
25 | 28 | import org.springframework.stereotype.Controller; |
26 | 29 | import org.springframework.util.Assert; |
27 | 30 | import org.springframework.util.CollectionUtils; |
| 31 | +import org.springframework.util.ObjectUtils; |
28 | 32 | import org.springframework.util.StringValueResolver; |
29 | 33 | import org.springframework.web.accept.ContentNegotiationManager; |
30 | 34 | import org.springframework.web.bind.annotation.CrossOrigin; |
@@ -190,15 +194,11 @@ protected boolean isHandler(Class<?> beanType) { |
190 | 194 | */ |
191 | 195 | @Override |
192 | 196 | protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { |
193 | | - RequestMappingInfo info = null; |
194 | | - RequestMapping methodAnnotation = AnnotationUtils.findAnnotation(method, RequestMapping.class); |
195 | | - if (methodAnnotation != null) { |
196 | | - RequestCondition<?> methodCondition = getCustomMethodCondition(method); |
197 | | - info = createRequestMappingInfo(methodAnnotation, methodCondition); |
198 | | - RequestMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class); |
199 | | - if (typeAnnotation != null) { |
200 | | - RequestCondition<?> typeCondition = getCustomTypeCondition(handlerType); |
201 | | - info = createRequestMappingInfo(typeAnnotation, typeCondition).combine(info); |
| 197 | + RequestMappingInfo info = createRequestMappingInfo(method); |
| 198 | + if (info != null) { |
| 199 | + RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType); |
| 200 | + if (typeInfo != null) { |
| 201 | + info = typeInfo.combine(info); |
202 | 202 | } |
203 | 203 | } |
204 | 204 | return info; |
@@ -235,20 +235,83 @@ protected RequestCondition<?> getCustomMethodCondition(Method method) { |
235 | 235 | } |
236 | 236 |
|
237 | 237 | /** |
238 | | - * Created a RequestMappingInfo from a RequestMapping annotation. |
| 238 | + * Transitional method used to invoke one of two createRequestMappingInfo |
| 239 | + * variants one of which is deprecated. |
239 | 240 | */ |
240 | | - protected RequestMappingInfo createRequestMappingInfo(RequestMapping annotation, RequestCondition<?> customCondition) { |
241 | | - String[] patterns = resolveEmbeddedValuesInPatterns(annotation.value()); |
242 | | - return new RequestMappingInfo( |
243 | | - annotation.name(), |
244 | | - new PatternsRequestCondition(patterns, getUrlPathHelper(), getPathMatcher(), |
245 | | - this.useSuffixPatternMatch, this.useTrailingSlashMatch, this.fileExtensions), |
246 | | - new RequestMethodsRequestCondition(annotation.method()), |
247 | | - new ParamsRequestCondition(annotation.params()), |
248 | | - new HeadersRequestCondition(annotation.headers()), |
249 | | - new ConsumesRequestCondition(annotation.consumes(), annotation.headers()), |
250 | | - new ProducesRequestCondition(annotation.produces(), annotation.headers(), this.contentNegotiationManager), |
251 | | - customCondition); |
| 241 | + private RequestMappingInfo createRequestMappingInfo(AnnotatedElement annotatedElement) { |
| 242 | + RequestMapping annotation; |
| 243 | + AnnotationAttributes attributes; |
| 244 | + RequestCondition<?> customCondition; |
| 245 | + String annotationType = RequestMapping.class.getName(); |
| 246 | + if (annotatedElement instanceof Class<?>) { |
| 247 | + Class<?> type = (Class<?>) annotatedElement; |
| 248 | + annotation = AnnotationUtils.findAnnotation(type, RequestMapping.class); |
| 249 | + attributes = AnnotatedElementUtils.getAnnotationAttributes(type, annotationType); |
| 250 | + customCondition = getCustomTypeCondition(type); |
| 251 | + } |
| 252 | + else { |
| 253 | + Method method = (Method) annotatedElement; |
| 254 | + annotation = AnnotationUtils.findAnnotation(method, RequestMapping.class); |
| 255 | + attributes = AnnotatedElementUtils.getAnnotationAttributes(method, annotationType); |
| 256 | + customCondition = getCustomMethodCondition(method); |
| 257 | + } |
| 258 | + RequestMappingInfo info = null; |
| 259 | + if (annotation != null) { |
| 260 | + info = createRequestMappingInfo(annotation, customCondition); |
| 261 | + if (info == null) { |
| 262 | + info = createRequestMappingInfo(attributes, customCondition); |
| 263 | + } |
| 264 | + } |
| 265 | + return info; |
| 266 | + } |
| 267 | + |
| 268 | + /** |
| 269 | + * Create a RequestMappingInfo from a RequestMapping annotation. |
| 270 | + * @deprecated as of 4.2 after the introduction of support for |
| 271 | + * {@code @RequestMapping} as meta-annotation. Please use |
| 272 | + * {@link #createRequestMappingInfo(AnnotationAttributes, RequestCondition)}. |
| 273 | + */ |
| 274 | + @Deprecated |
| 275 | + protected RequestMappingInfo createRequestMappingInfo(RequestMapping annotation, |
| 276 | + RequestCondition<?> customCondition) { |
| 277 | + |
| 278 | + return null; |
| 279 | + } |
| 280 | + |
| 281 | + /** |
| 282 | + * Create a RequestMappingInfo from the attributes of an |
| 283 | + * {@code @RequestMapping} annotation or a meta-annotation, i.e. a custom |
| 284 | + * annotation annotated with {@code @RequestMapping}. |
| 285 | + * @since 4.2 |
| 286 | + */ |
| 287 | + protected RequestMappingInfo createRequestMappingInfo(AnnotationAttributes attributes, |
| 288 | + RequestCondition<?> customCondition) { |
| 289 | + |
| 290 | + String mappingName = attributes.getString("name"); |
| 291 | + |
| 292 | + String[] paths = attributes.getStringArray("path"); |
| 293 | + paths = ObjectUtils.isEmpty(paths) ? attributes.getStringArray("value") : paths; |
| 294 | + PatternsRequestCondition patternsCondition = new PatternsRequestCondition( |
| 295 | + resolveEmbeddedValuesInPatterns(paths), getUrlPathHelper(), getPathMatcher(), |
| 296 | + this.useSuffixPatternMatch, this.useTrailingSlashMatch, this.fileExtensions); |
| 297 | + |
| 298 | + RequestMethod[] methods = (RequestMethod[]) attributes.get("method"); |
| 299 | + RequestMethodsRequestCondition methodsCondition = new RequestMethodsRequestCondition(methods); |
| 300 | + |
| 301 | + String[] params = attributes.getStringArray("params"); |
| 302 | + ParamsRequestCondition paramsCondition = new ParamsRequestCondition(params); |
| 303 | + |
| 304 | + String[] headers = attributes.getStringArray("headers"); |
| 305 | + String[] consumes = attributes.getStringArray("consumes"); |
| 306 | + String[] produces = attributes.getStringArray("produces"); |
| 307 | + |
| 308 | + HeadersRequestCondition headersCondition = new HeadersRequestCondition(headers); |
| 309 | + ConsumesRequestCondition consumesCondition = new ConsumesRequestCondition(consumes, headers); |
| 310 | + ProducesRequestCondition producesCondition = new ProducesRequestCondition(produces, |
| 311 | + headers, this.contentNegotiationManager); |
| 312 | + |
| 313 | + return new RequestMappingInfo(mappingName, patternsCondition, methodsCondition, paramsCondition, |
| 314 | + headersCondition, consumesCondition, producesCondition, customCondition); |
252 | 315 | } |
253 | 316 |
|
254 | 317 | /** |
@@ -320,7 +383,8 @@ else if (annotation.allowCredentials().equalsIgnoreCase("false")) { |
320 | 383 | config.setAllowCredentials(false); |
321 | 384 | } |
322 | 385 | else if (!annotation.allowCredentials().isEmpty()) { |
323 | | - throw new IllegalStateException("AllowCredentials value must be \"true\", \"false\" or \"\" (empty string), current value is " + annotation.allowCredentials()); |
| 386 | + throw new IllegalStateException("AllowCredentials value must be \"true\", \"false\" " + |
| 387 | + "or \"\" (empty string), current value is " + annotation.allowCredentials()); |
324 | 388 | } |
325 | 389 | if (annotation.maxAge() != -1 && config.getMaxAge() == null) { |
326 | 390 | config.setMaxAge(annotation.maxAge()); |
|
0 commit comments