From fa0b683161f59e5e733a34a9cdfaf484da80e856 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 14 Jun 2011 09:20:07 +0000 Subject: [PATCH] Extract base class from RequestMappingHandlerMapping, one that allows for discovering request mappings from something other than annotations --- .../{annotation => }/RequestMappingInfo.java | 2 +- .../RequestMappingInfoHandlerMapping.java | 228 ++++++++++++++++++ .../RequestMappingHandlerMapping.java | 204 +--------------- .../method/condition/RequestCondition.java | 3 +- .../RequestMappingInfoComparatorTests.java | 22 +- ...equestMappingInfoHandlerMappingTests.java} | 35 ++- .../RequestMappingInfoTests.java | 3 +- 7 files changed, 285 insertions(+), 212 deletions(-) rename org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/{annotation => }/RequestMappingInfo.java (99%) create mode 100644 org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java rename org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/{annotation => }/RequestMappingInfoComparatorTests.java (89%) rename org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/{annotation/RequestMappingHandlerMappingTests.java => RequestMappingInfoHandlerMappingTests.java} (80%) rename org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/{annotation => }/RequestMappingInfoTests.java (98%) diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfo.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java similarity index 99% rename from org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfo.java rename to org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java index ad934dd9302..b22ae2c2ab2 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfo.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.web.servlet.mvc.method.annotation; +package org.springframework.web.servlet.mvc.method; import java.util.ArrayList; import java.util.Collection; diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java new file mode 100644 index 00000000000..8a9118d4347 --- /dev/null +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java @@ -0,0 +1,228 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.servlet.mvc.method; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; + +import org.springframework.http.MediaType; +import org.springframework.util.PathMatcher; +import org.springframework.util.StringUtils; +import org.springframework.web.HttpMediaTypeNotAcceptableException; +import org.springframework.web.HttpMediaTypeNotSupportedException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping; + +/** + * An {@link AbstractHandlerMethodMapping} variant that uses {@link RequestMappingInfo} to represent request + * mapping conditions. + * + * @author Arjen Poutsma + * @author Rossen Stoyanchev + * @since 3.1.0 + */ +public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping { + + @Override + protected void handlerMethodsInitialized(Map handlerMethods) { + List mappings = new ArrayList(handlerMethods.keySet()); + while (mappings.size() > 1) { + RequestMappingInfo mapping = mappings.remove(0); + for (RequestMappingInfo otherMapping : mappings) { + // further validate mapping conditions + } + } + } + + @Override + protected Set getMappingPaths(RequestMappingInfo mapping) { + return mapping.getPatterns(); + } + + /** + * Returns a new {@link RequestMappingInfo} with attributes matching to the current request or {@code null}. + * + * @see RequestMappingInfo#getMatchingRequestMapping(String, HttpServletRequest, PathMatcher) + */ + @Override + protected RequestMappingInfo getMatchingMapping(RequestMappingInfo mapping, + String lookupPath, + HttpServletRequest request) { + return mapping.getMatchingRequestMapping(lookupPath, request, getPathMatcher()); + } + + /** + * Returns a {@link Comparator} that can be used to sort and select the best matching {@link RequestMappingInfo}. + */ + @Override + protected Comparator getMappingComparator(String lookupPath, HttpServletRequest request) { + return new RequestMappingInfoComparator(lookupPath, request); + } + + /** + * Exposes URI template variables and producible media types as request attributes. + * + * @see HandlerMapping#URI_TEMPLATE_VARIABLES_ATTRIBUTE + * @see HandlerMapping#PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE + */ + @Override + protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) { + super.handleMatch(info, lookupPath, request); + + String pattern = info.getPatterns().iterator().next(); + Map uriTemplateVariables = getPathMatcher().extractUriTemplateVariables(pattern, lookupPath); + request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables); + + if (!info.getProduces().isEmpty()) { + Set mediaTypes = info.getProduces().getMediaTypes(); + request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes); + } + } + + /** + * Iterates all {@link RequestMappingInfo}s looking for mappings that match by URL but not by HTTP method. + * + * @throws HttpRequestMethodNotSupportedException if there are matches by URL but not by HTTP method + */ + @Override + protected HandlerMethod handleNoMatch(Set requestMappingInfos, + String lookupPath, + HttpServletRequest request) throws ServletException { + Set allowedMethods = new HashSet(6); + Set consumableMediaTypes = new HashSet(); + Set producibleMediaTypes = new HashSet(); + for (RequestMappingInfo info : requestMappingInfos) { + for (String pattern : info.getPatterns()) { + if (getPathMatcher().match(pattern, lookupPath)) { + if (!info.getMethods().match(request)) { + for (RequestMethod method : info.getMethods().getMethods()) { + allowedMethods.add(method.name()); + } + } + if (!info.getConsumes().match(request)) { + consumableMediaTypes.addAll(info.getConsumes().getMediaTypes()); + } + if (!info.getProduces().match(request)) { + producibleMediaTypes.addAll(info.getProduces().getMediaTypes()); + } + } + } + } + if (!allowedMethods.isEmpty()) { + throw new HttpRequestMethodNotSupportedException(request.getMethod(), allowedMethods); + } + else if (!consumableMediaTypes.isEmpty()) { + MediaType contentType = null; + if (StringUtils.hasLength(request.getContentType())) { + contentType = MediaType.parseMediaType(request.getContentType()); + } + throw new HttpMediaTypeNotSupportedException(contentType, new ArrayList(consumableMediaTypes)); + } + else if (!producibleMediaTypes.isEmpty()) { + throw new HttpMediaTypeNotAcceptableException(new ArrayList(producibleMediaTypes)); + } + else { + return null; + } + } + + /** + * A comparator for {@link RequestMappingInfo}s. Effective comparison can only be done in the context of a specific + * request. For example not all {@link RequestMappingInfo} patterns may apply to the current request. Therefore an + * HttpServletRequest is required as input. + * + *

Furthermore, the following assumptions are made about the input RequestMappings:

  • Each RequestMappingInfo + * has been fully matched to the request
  • The RequestMappingInfo contains matched patterns only
  • Patterns are + * ordered with the best matching pattern at the top
+ * + * @see RequestMappingInfoHandlerMapping#getMatchingMapping(RequestMappingInfo, String, HttpServletRequest) + */ + private class RequestMappingInfoComparator implements Comparator { + + private Comparator patternComparator; + + private List requestAcceptHeader; + + public RequestMappingInfoComparator(String lookupPath, HttpServletRequest request) { + this.patternComparator = getPathMatcher().getPatternComparator(lookupPath); + String acceptHeader = request.getHeader("Accept"); + this.requestAcceptHeader = MediaType.parseMediaTypes(acceptHeader); + MediaType.sortByQualityValue(this.requestAcceptHeader); + } + + public int compare(RequestMappingInfo mapping, RequestMappingInfo otherMapping) { + int result = comparePatterns(mapping.getPatterns(), otherMapping.getPatterns()); + if (result != 0) { + return result; + } + result = mapping.getParams().compareTo(otherMapping.getParams()); + if (result != 0) { + return result; + } + result = mapping.getHeaders().compareTo(otherMapping.getHeaders()); + if (result != 0) { + return result; + } + result = mapping.getConsumes().compareTo(otherMapping.getConsumes()); + if (result != 0) { + return result; + } + result = mapping.getProduces().compareTo(otherMapping.getProduces(), this.requestAcceptHeader); + if (result != 0) { + return result; + } + result = mapping.getMethods().compareTo(otherMapping.getMethods()); + if (result != 0) { + return result; + } + return 0; + } + + private int comparePatterns(Set patterns, Set otherPatterns) { + Iterator iterator = patterns.iterator(); + Iterator iteratorOther = otherPatterns.iterator(); + while (iterator.hasNext() && iteratorOther.hasNext()) { + int result = patternComparator.compare(iterator.next(), iteratorOther.next()); + if (result != 0) { + return result; + } + } + if (iterator.hasNext()) { + return -1; + } + else if (iteratorOther.hasNext()) { + return 1; + } + else { + return 0; + } + } + + } + +} diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java index 1ac4ac66632..a0102faaa70 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java @@ -17,42 +17,25 @@ package org.springframework.web.servlet.mvc.method.annotation; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.util.PathMatcher; -import org.springframework.util.StringUtils; -import org.springframework.web.HttpMediaTypeNotAcceptableException; -import org.springframework.web.HttpMediaTypeNotSupportedException; -import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.HandlerMapping; -import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory; /** - * An {@link AbstractHandlerMethodMapping} variant that uses {@link RequestMappingInfo}s for the registration and the - * lookup of {@link HandlerMethod}s. + * A sub-class of {@link RequestMappingInfoHandlerMapping} that prepares {@link RequestMappingInfo}s + * from @{@link RequestMapping} annotations on @{@link Controller} classes. * * @author Arjen Poutsma * @author Rossen Stoyanchev * @since 3.1.0 */ -public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping { +public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping { /** * {@inheritDoc} The handler determination in this method is made based on the presence of a type-level {@link @@ -63,17 +46,6 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping handlerMethods) { - List mappings = new ArrayList(handlerMethods.keySet()); - while (mappings.size() > 1) { - RequestMappingInfo mapping = mappings.remove(0); - for (RequestMappingInfo otherMapping : mappings) { - // further validate mapping conditions - } - } - } - /** * Provides a {@link RequestMappingInfo} for the given method.

Only {@link RequestMapping @RequestMapping}-annotated * methods are considered. Type-level {@link RequestMapping @RequestMapping} annotations are also detected and their @@ -112,170 +84,4 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping getMappingPaths(RequestMappingInfo mapping) { - return mapping.getPatterns(); - } - - /** - * Returns a new {@link RequestMappingInfo} with attributes matching to the current request or {@code null}. - * - * @see RequestMappingInfo#getMatchingRequestMapping(String, HttpServletRequest, PathMatcher) - */ - @Override - protected RequestMappingInfo getMatchingMapping(RequestMappingInfo mapping, - String lookupPath, - HttpServletRequest request) { - return mapping.getMatchingRequestMapping(lookupPath, request, getPathMatcher()); - } - - /** - * Returns a {@link Comparator} that can be used to sort and select the best matching {@link RequestMappingInfo}. - */ - @Override - protected Comparator getMappingComparator(String lookupPath, HttpServletRequest request) { - return new RequestMappingInfoComparator(lookupPath, request); - } - - /** - * Exposes URI template variables and producible media types as request attributes. - * - * @see HandlerMapping#URI_TEMPLATE_VARIABLES_ATTRIBUTE - * @see HandlerMapping#PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE - */ - @Override - protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) { - super.handleMatch(info, lookupPath, request); - - String pattern = info.getPatterns().iterator().next(); - Map uriTemplateVariables = getPathMatcher().extractUriTemplateVariables(pattern, lookupPath); - request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables); - - if (!info.getProduces().isEmpty()) { - Set mediaTypes = info.getProduces().getMediaTypes(); - request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes); - } - } - - /** - * Iterates all {@link RequestMappingInfo}s looking for mappings that match by URL but not by HTTP method. - * - * @throws HttpRequestMethodNotSupportedException if there are matches by URL but not by HTTP method - */ - @Override - protected HandlerMethod handleNoMatch(Set requestMappingInfos, - String lookupPath, - HttpServletRequest request) throws ServletException { - Set allowedMethods = new HashSet(6); - Set consumableMediaTypes = new HashSet(); - Set producibleMediaTypes = new HashSet(); - for (RequestMappingInfo info : requestMappingInfos) { - for (String pattern : info.getPatterns()) { - if (getPathMatcher().match(pattern, lookupPath)) { - if (!info.getMethods().match(request)) { - for (RequestMethod method : info.getMethods().getMethods()) { - allowedMethods.add(method.name()); - } - } - if (!info.getConsumes().match(request)) { - consumableMediaTypes.addAll(info.getConsumes().getMediaTypes()); - } - if (!info.getProduces().match(request)) { - producibleMediaTypes.addAll(info.getProduces().getMediaTypes()); - } - } - } - } - if (!allowedMethods.isEmpty()) { - throw new HttpRequestMethodNotSupportedException(request.getMethod(), allowedMethods); - } - else if (!consumableMediaTypes.isEmpty()) { - MediaType contentType = null; - if (StringUtils.hasLength(request.getContentType())) { - contentType = MediaType.parseMediaType(request.getContentType()); - } - throw new HttpMediaTypeNotSupportedException(contentType, new ArrayList(consumableMediaTypes)); - } - else if (!producibleMediaTypes.isEmpty()) { - throw new HttpMediaTypeNotAcceptableException(new ArrayList(producibleMediaTypes)); - } - else { - return null; - } - } - - /** - * A comparator for {@link RequestMappingInfo}s. Effective comparison can only be done in the context of a specific - * request. For example not all {@link RequestMappingInfo} patterns may apply to the current request. Therefore an - * HttpServletRequest is required as input. - * - *

Furthermore, the following assumptions are made about the input RequestMappings:

  • Each RequestMappingInfo - * has been fully matched to the request
  • The RequestMappingInfo contains matched patterns only
  • Patterns are - * ordered with the best matching pattern at the top
- * - * @see RequestMappingHandlerMapping#getMatchingMapping(RequestMappingInfo, String, HttpServletRequest) - */ - private class RequestMappingInfoComparator implements Comparator { - - private Comparator patternComparator; - - private List requestAcceptHeader; - - public RequestMappingInfoComparator(String lookupPath, HttpServletRequest request) { - this.patternComparator = getPathMatcher().getPatternComparator(lookupPath); - String acceptHeader = request.getHeader("Accept"); - this.requestAcceptHeader = MediaType.parseMediaTypes(acceptHeader); - MediaType.sortByQualityValue(this.requestAcceptHeader); - } - - public int compare(RequestMappingInfo mapping, RequestMappingInfo otherMapping) { - int result = comparePatterns(mapping.getPatterns(), otherMapping.getPatterns()); - if (result != 0) { - return result; - } - result = mapping.getParams().compareTo(otherMapping.getParams()); - if (result != 0) { - return result; - } - result = mapping.getHeaders().compareTo(otherMapping.getHeaders()); - if (result != 0) { - return result; - } - result = mapping.getConsumes().compareTo(otherMapping.getConsumes()); - if (result != 0) { - return result; - } - result = mapping.getProduces().compareTo(otherMapping.getProduces(), this.requestAcceptHeader); - if (result != 0) { - return result; - } - result = mapping.getMethods().compareTo(otherMapping.getMethods()); - if (result != 0) { - return result; - } - return 0; - } - - private int comparePatterns(Set patterns, Set otherPatterns) { - Iterator iterator = patterns.iterator(); - Iterator iteratorOther = otherPatterns.iterator(); - while (iterator.hasNext() && iteratorOther.hasNext()) { - int result = patternComparator.compare(iterator.next(), iteratorOther.next()); - if (result != 0) { - return result; - } - } - if (iterator.hasNext()) { - return -1; - } - else if (iteratorOther.hasNext()) { - return 1; - } - else { - return 0; - } - } - - } - } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition.java index ee4ac36c1a5..74619e7c9e6 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition.java @@ -19,8 +19,7 @@ package org.springframework.web.servlet.mvc.method.condition; import javax.servlet.http.HttpServletRequest; /** - * Defines the contract for conditions that must be met before an incoming request matches a {@link - * org.springframework.web.servlet.mvc.method.annotation.RequestMappingInfo RequestKey}. + * Defines the contract for conditions that must be met given an incoming request. * *

Implementations of this interface are created by the {@link RequestConditionFactory}. * diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoComparatorTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoComparatorTests.java similarity index 89% rename from org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoComparatorTests.java rename to org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoComparatorTests.java index dc05c3ca4e1..01ae7f41a5d 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoComparatorTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoComparatorTests.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package org.springframework.web.servlet.mvc.method.annotation; +package org.springframework.web.servlet.mvc.method; +import java.lang.reflect.Method; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -25,6 +26,8 @@ import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory; import org.springframework.web.util.UrlPathHelper; @@ -39,13 +42,13 @@ import static org.junit.Assert.*; */ public class RequestMappingInfoComparatorTests { - private RequestMappingHandlerMapping handlerMapping; + private TestRequestMappingInfoHandlerMapping handlerMapping; private MockHttpServletRequest request; @Before public void setup() { - this.handlerMapping = new RequestMappingHandlerMapping(); + this.handlerMapping = new TestRequestMappingInfoHandlerMapping(); this.request = new MockHttpServletRequest(); } @@ -148,5 +151,18 @@ public class RequestMappingInfoComparatorTests { assertTrue(comparator.compare(html, xml) > 0); assertTrue(comparator.compare(xml, html) < 0); } + + private static class TestRequestMappingInfoHandlerMapping extends RequestMappingInfoHandlerMapping { + + @Override + protected boolean isHandler(Class beanType) { + return false; + } + + @Override + protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { + return null; + } + } } \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMappingTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java similarity index 80% rename from org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMappingTests.java rename to org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java index 99da971c7e6..62861a1f52e 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMappingTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.web.servlet.mvc.method.annotation; +package org.springframework.web.servlet.mvc.method; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -23,12 +23,14 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.Map; import org.junit.Before; import org.junit.Test; import org.springframework.context.support.StaticApplicationContext; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.HttpRequestMethodNotSupportedException; @@ -40,6 +42,9 @@ import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import org.springframework.web.servlet.handler.MappedInterceptor; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory; import org.springframework.web.util.UrlPathHelper; /** @@ -48,9 +53,9 @@ import org.springframework.web.util.UrlPathHelper; * @author Arjen Poutsma * @author Rossen Stoyanchev */ -public class RequestMappingHandlerMappingTests { +public class RequestMappingInfoHandlerMappingTests { - private RequestMappingHandlerMapping mapping; + private TestRequestMappingInfoHandlerMapping mapping; private Handler handler; @@ -73,7 +78,7 @@ public class RequestMappingHandlerMappingTests { StaticApplicationContext context = new StaticApplicationContext(); context.registerSingleton("handler", handler.getClass()); - mapping = new RequestMappingHandlerMapping(); + mapping = new TestRequestMappingInfoHandlerMapping(); mapping.setApplicationContext(context); } @@ -148,7 +153,7 @@ public class RequestMappingHandlerMappingTests { StaticApplicationContext context = new StaticApplicationContext(); context.registerSingleton("handler", handler.getClass()); - mapping = new RequestMappingHandlerMapping(); + mapping = new TestRequestMappingInfoHandlerMapping(); mapping.setInterceptors(new Object[] { mappedInterceptor }); mapping.setApplicationContext(context); @@ -163,7 +168,6 @@ public class RequestMappingHandlerMappingTests { @SuppressWarnings("unused") @Controller - @RequestMapping private static class Handler { @RequestMapping(value = "/foo", method = RequestMethod.GET) @@ -182,5 +186,24 @@ public class RequestMappingHandlerMappingTests { public void empty() { } } + + private static class TestRequestMappingInfoHandlerMapping extends RequestMappingInfoHandlerMapping { + + @Override + protected boolean isHandler(Class beanType) { + return AnnotationUtils.findAnnotation(beanType, Controller.class) != null; + } + + @Override + protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { + RequestMapping annotation = AnnotationUtils.findAnnotation(method, RequestMapping.class); + return new RequestMappingInfo(Arrays.asList(annotation.value()), + RequestConditionFactory.parseMethods(annotation.method()), + RequestConditionFactory.parseParams(annotation.params()), + RequestConditionFactory.parseHeaders(annotation.headers()), + RequestConditionFactory.parseConsumes(annotation.consumes(), annotation.headers()), + RequestConditionFactory.parseProduces(annotation.produces(), annotation.headers())); + } + } } \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java similarity index 98% rename from org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoTests.java rename to org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java index 472f6a0f1eb..f03017af057 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.web.servlet.mvc.method.annotation; +package org.springframework.web.servlet.mvc.method; import org.junit.Test; @@ -22,6 +22,7 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.util.AntPathMatcher; import org.springframework.util.PathMatcher; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory; import org.springframework.web.util.UrlPathHelper;