SWF-8214 javadoc updates
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4218 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
ab4a3568b1
commit
19fdaaa74a
|
|
@ -36,8 +36,22 @@ import org.springframework.web.method.HandlerMethodSelector;
|
|||
|
||||
/**
|
||||
* Abstract base class for {@link org.springframework.web.servlet.HandlerMapping HandlerMapping} implementations that
|
||||
* support {@link HandlerMethod}s.
|
||||
* support mapping requests to {@link HandlerMethod}s rather than to handlers.
|
||||
*
|
||||
* <p>Each {@link HandlerMethod} is registered with a unique key. Subclasses define the key type and how to create it
|
||||
* for a given handler method. Keys represent conditions for matching a handler method to a request.
|
||||
*
|
||||
* <p>Subclasses must also define how to create a key for an incoming request. The resulting key is used to perform
|
||||
* a {@link HandlerMethod} lookup possibly resulting in a direct match. However, when a map lookup is insufficient,
|
||||
* the keys of all handler methods are iterated and subclasses are allowed to make an exhaustive check of key
|
||||
* conditions against the request.
|
||||
*
|
||||
* <p>Since there can be more than one matching key for a request, subclasses must define a comparator for sorting
|
||||
* the keys of matching handler methods in order to find the most specific match.
|
||||
*
|
||||
* @param <T> A unique key for the registration of mapped {@link HandlerMethod}s representing the conditions to
|
||||
* match a handler method to a request.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
|
|
@ -80,6 +94,9 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
|||
*/
|
||||
protected abstract boolean isHandler(String beanName);
|
||||
|
||||
/**
|
||||
* Detect and register handler methods for the specified handler.
|
||||
*/
|
||||
private void detectHandlerMethods(final String handlerName) {
|
||||
Class<?> handlerType = getApplicationContext().getType(handlerName);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,18 @@ import org.springframework.web.servlet.mvc.method.condition.RequestConditionFact
|
|||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Contains a set of conditions to match to a given request such as URL patterns, HTTP methods, request
|
||||
* parameters and headers.
|
||||
*
|
||||
* <p>A {@link RequestKey} can be combined with another {@link RequestKey} resulting in a new {@link RequestKey}
|
||||
* with conditions from both (see {@link #combine(RequestKey, PathMatcher)}).
|
||||
*
|
||||
* <p>A {@link RequestKey} can be matched to a request resulting in a new {@link RequestKey} with the subset of
|
||||
* conditions relevant to the request (see {@link #getMatchingKey(HttpServletRequest, PathMatcher, UrlPathHelper)}).
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
public final class RequestKey {
|
||||
|
||||
|
|
@ -52,14 +60,19 @@ public final class RequestKey {
|
|||
|
||||
private int hash;
|
||||
|
||||
/**
|
||||
* Creates a new {@code RequestKey} instance with the given URL patterns and HTTP methods.
|
||||
*
|
||||
* <p>Package protected for testing purposes.
|
||||
*/
|
||||
RequestKey(Collection<String> patterns, Collection<RequestMethod> methods) {
|
||||
this(patterns, methods, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code RequestKey} instance with the given parameters.
|
||||
*
|
||||
* <p/>Package protected for testing purposes.
|
||||
* Creates a new {@code RequestKey} instance with a full set of conditions.
|
||||
*
|
||||
* <p>Package protected for testing purposes.
|
||||
*/
|
||||
RequestKey(Collection<String> patterns,
|
||||
Collection<RequestMethod> methods,
|
||||
|
|
@ -152,12 +165,22 @@ public final class RequestKey {
|
|||
}
|
||||
|
||||
/**
|
||||
* Combines this {@code RequestKey} with another. The typical use case for this is combining type
|
||||
* and method-level {@link RequestMapping @RequestMapping} annotations.
|
||||
*
|
||||
* @param methodKey the method-level RequestKey
|
||||
* Combines this {@code RequestKey} with another as follows:
|
||||
* <ul>
|
||||
* <li>URL patterns:
|
||||
* <ul>
|
||||
* <li>If both keys have path patterns combine them according to the rules of the given {@link PathMatcher}.
|
||||
* <li>If either key contains path patterns but not both use only what is available.
|
||||
* <li>If neither key contains path patterns use "/".
|
||||
* </ul>
|
||||
* <li>HTTP methods are combined as union of all HTTP methods listed in both keys.
|
||||
* <li>Request parameter are combined into a logical AND.
|
||||
* <li>Request header are combined into a logical AND.
|
||||
* <li>Consumes .. TODO
|
||||
* </ul>
|
||||
* @param methodKey the key to combine with
|
||||
* @param pathMatcher to {@linkplain PathMatcher#combine(String, String) combine} the patterns
|
||||
* @return the combined request key
|
||||
* @return a new request key containing conditions from both keys
|
||||
*/
|
||||
public RequestKey combine(RequestKey methodKey, PathMatcher pathMatcher) {
|
||||
Set<String> patterns = combinePatterns(this.patterns, methodKey.patterns, pathMatcher);
|
||||
|
|
@ -199,15 +222,18 @@ public final class RequestKey {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@code RequestKey} that contains all matching attributes of this key, given the {@link
|
||||
* HttpServletRequest}. Matching patterns in the returned RequestKey are sorted according to {@link
|
||||
* PathMatcher#getPatternComparator(String)} with the best matching pattern at the top.
|
||||
*
|
||||
* @param request the servlet request
|
||||
* @param pathMatcher to {@linkplain PathMatcher#match(String, String) match} patterns
|
||||
* @param urlPathHelper to create the {@linkplain UrlPathHelper#getLookupPathForRequest(HttpServletRequest) lookup
|
||||
* path}
|
||||
* @return a new request key that contains all matching attributes
|
||||
* Returns a new {@code RequestKey} that contains all conditions of this key that are relevant to the request.
|
||||
* <ul>
|
||||
* <li>The list of URL path patterns is trimmed to contain the patterns that match the URL with matching patterns
|
||||
* sorted via {@link PathMatcher#getPatternComparator(String)}.
|
||||
* <li>The list of HTTP methods is trimmed to contain only the method of the request.
|
||||
* <li>Request parameter and request header conditions are included in full.
|
||||
* <li>The list of consumes conditions is trimmed and sorted to match the request "Content-Type" header.
|
||||
* </ul>
|
||||
* @param request the current request
|
||||
* @param pathMatcher to check for matching patterns
|
||||
* @param urlPathHelper to derive the lookup path for the request
|
||||
* @return a new request key that contains all matching attributes, or {@code null} if not all conditions match
|
||||
*/
|
||||
public RequestKey getMatchingKey(HttpServletRequest request, PathMatcher pathMatcher, UrlPathHelper urlPathHelper) {
|
||||
if (!checkMethod(request) || !paramsCondition.match(request) || !headersCondition.match(request) ||
|
||||
|
|
@ -217,7 +243,7 @@ public final class RequestKey {
|
|||
else {
|
||||
List<String> matchingPatterns = getMatchingPatterns(request, pathMatcher, urlPathHelper);
|
||||
if (!matchingPatterns.isEmpty()) {
|
||||
Set<RequestMethod> matchingMethods = getMatchingMethods(request);
|
||||
Set<RequestMethod> matchingMethods = getMatchingMethod(request);
|
||||
return new RequestKey(matchingPatterns, matchingMethods, this.paramsCondition, this.headersCondition,
|
||||
this.consumesCondition);
|
||||
}
|
||||
|
|
@ -245,7 +271,7 @@ public final class RequestKey {
|
|||
return matchingPatterns;
|
||||
}
|
||||
|
||||
private Set<RequestMethod> getMatchingMethods(HttpServletRequest request) {
|
||||
private Set<RequestMethod> getMatchingMethod(HttpServletRequest request) {
|
||||
if (this.methods.isEmpty()) {
|
||||
return this.methods;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
|
|
@ -44,7 +45,22 @@ import org.springframework.web.servlet.handler.MappedInterceptors;
|
|||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* An {@link AbstractHandlerMethodMapping} variant that uses {@link RequestKey}s for the registration and the lookup
|
||||
* of {@link HandlerMethod}s.
|
||||
*
|
||||
* <p>A {@link RequestKey} for an incoming request contains the URL and the HTTP method of the request.
|
||||
* A {@link RequestKey} for a handler method contains all conditions found in the method @{@link RequestMapping}
|
||||
* annotation combined with all conditions found in the type @{@link RequestMapping} annotation, if present.
|
||||
*
|
||||
* <p>An incoming request matches to a handler method directly when a @{@link RequestMapping} annotation contains
|
||||
* a single, non-pattern URL and a single HTTP method. When a {@link RequestKey} contains additional conditions
|
||||
* (e.g. more URL patterns, request parameters, headers, etc) those conditions must be checked against the
|
||||
* request rather than against the key that represents it. This results in the creation of a new handler method
|
||||
* {@link RequestKey} with the subset of conditions relevant to the current request (see
|
||||
* {@link RequestKey#getMatchingKey(HttpServletRequest, PathMatcher, UrlPathHelper)}).
|
||||
* Such keys can then be compared against each other, in the context of the current request, making it possible
|
||||
* to select to the best matching {@link RequestKey} in case of multiple matches and also the best matching
|
||||
* pattern within the selected key.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
|
|
@ -168,6 +184,18 @@ public class RequestMappingHandlerMethodMapping extends AbstractHandlerMethodMap
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link RequestKey} with attributes matching to the current request or {@code null}.
|
||||
* @see RequestKey#getMatchingKey(HttpServletRequest, PathMatcher, UrlPathHelper)
|
||||
*/
|
||||
@Override
|
||||
protected RequestKey getMatchingKey(RequestKey key, HttpServletRequest request) {
|
||||
return key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Comparator} that can be used to sort and select the best matching {@link RequestKey}.
|
||||
*/
|
||||
@Override
|
||||
protected Comparator<RequestKey> getKeyComparator(HttpServletRequest request) {
|
||||
return new RequestKeyComparator(request);
|
||||
|
|
@ -181,24 +209,10 @@ public class RequestMappingHandlerMethodMapping extends AbstractHandlerMethodMap
|
|||
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RequestKey getMatchingKey(RequestKey key, HttpServletRequest request) {
|
||||
return key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
|
||||
HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
|
||||
if (this.mappedInterceptors != null) {
|
||||
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
|
||||
HandlerInterceptor[] handlerInterceptors = mappedInterceptors.getInterceptors(lookupPath, pathMatcher);
|
||||
if (handlerInterceptors.length > 0) {
|
||||
chain.addInterceptors(handlerInterceptors);
|
||||
}
|
||||
}
|
||||
return chain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates all {@link RequestKey}s looking for keys that match by URL but not by HTTP method.
|
||||
* @exception HttpRequestMethodNotSupportedException if there are matches by URL but not by HTTP method
|
||||
*/
|
||||
@Override
|
||||
protected HandlerMethod handleNoMatch(Set<RequestKey> requestKeys, HttpServletRequest request)
|
||||
throws HttpRequestMethodNotSupportedException {
|
||||
|
|
@ -223,13 +237,29 @@ public class RequestMappingHandlerMethodMapping extends AbstractHandlerMethodMap
|
|||
}
|
||||
|
||||
/**
|
||||
* A comparator for RequestKey types. Effective comparison can only be done in the context of a specific request. For
|
||||
* example not all configured patterns may apply to the current request. Therefore an HttpServletRequest is required as
|
||||
* input.
|
||||
* Adds mapped interceptors to the handler execution chain.
|
||||
*/
|
||||
@Override
|
||||
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
|
||||
HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
|
||||
if (this.mappedInterceptors != null) {
|
||||
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
|
||||
HandlerInterceptor[] handlerInterceptors = mappedInterceptors.getInterceptors(lookupPath, pathMatcher);
|
||||
if (handlerInterceptors.length > 0) {
|
||||
chain.addInterceptors(handlerInterceptors);
|
||||
}
|
||||
}
|
||||
return chain;
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparator for {@link RequestKey}s. Effective comparison can only be done in the context of a
|
||||
* specific request. For example not all {@link RequestKey} patterns may apply to the current request.
|
||||
* Therefore an HttpServletRequest is required as input.
|
||||
*
|
||||
* Furthermore, the following assumptions are made about the input RequestKeys: <ul> <li>Each RequestKey has been fully
|
||||
* matched to the request <li>The RequestKey contains matched patterns only <li>Patterns are ordered with the best
|
||||
* matching pattern at the top </ul>
|
||||
* <p>Furthermore, the following assumptions are made about the input RequestKeys:
|
||||
* <ul><li>Each RequestKey has been fully matched to the request <li>The RequestKey contains matched
|
||||
* patterns only <li>Patterns are ordered with the best matching pattern at the top </ul>
|
||||
*
|
||||
* @see RequestMappingHandlerMethodMapping#getMatchingKey(RequestKey, HttpServletRequest)
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue