Browse Source

SWF-8214 javadoc updates

pull/7/head
Rossen Stoyanchev 14 years ago
parent
commit
6e03b4dd64
  1. 19
      org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
  2. 66
      org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestKey.java
  3. 80
      org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodMapping.java

19
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java

@ -36,8 +36,22 @@ import org.springframework.web.method.HandlerMethodSelector; @@ -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 @@ -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);

66
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestKey.java

@ -33,10 +33,18 @@ import org.springframework.web.servlet.mvc.method.condition.RequestConditionFact @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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;
}

80
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodMapping.java

@ -23,6 +23,7 @@ import java.util.Iterator; @@ -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; @@ -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 @@ -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 @@ -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 @@ -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…
Cancel
Save