|
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