implementations. Provides infrastructure for mapping handlers to URLs and configurable
URL lookup. For information on the latter, see "alwaysUseFullPath" property.
Supports direct matches, e.g. a registered "/test" matches "/test", and
various Ant-style pattern matches, e.g. a registered "/t*" pattern matches
both "/test" and "/team", "/test/*" matches all paths in the "/test" directory,
"/test/**" matches all paths below "/test". For details, see the
AntPathMatcher javadoc.
Will search all path patterns to find the most exact match for the
current request path. The most exact match is defined as the longest
path pattern that matches the current request path.
| Method from org.springframework.web.servlet.handler.AbstractUrlHandlerMapping Detail: |
protected Object buildPathExposingHandler(Object rawHandler,
String pathWithinMapping) {
// Bean name or resolved handler?
if (rawHandler instanceof String) {
String handlerName = (String) rawHandler;
rawHandler = getApplicationContext().getBean(handlerName);
}
HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler);
chain.addInterceptor(new PathExposingHandlerInterceptor(pathWithinMapping));
return chain;
}
|
protected void exposePathWithinMapping(String pathWithinMapping,
HttpServletRequest request) {
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping);
}
Expose the path within the current mapping as request attribute. |
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
if (logger.isDebugEnabled()) {
logger.debug("Looking up handler for [" + lookupPath + "]");
}
Object handler = lookupHandler(lookupPath, request);
if (handler == null) {
// We need to care for the default handler directly, since we need to
// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
Object rawHandler = null;
if ("/".equals(lookupPath)) {
rawHandler = getRootHandler();
}
if (rawHandler == null) {
rawHandler = getDefaultHandler();
}
if (rawHandler != null) {
validateHandler(rawHandler, request);
handler = buildPathExposingHandler(rawHandler, lookupPath);
}
}
return handler;
}
Look up a handler for the URL path of the given request. |
public final Map getHandlerMap() {
return Collections.unmodifiableMap(this.handlerMap);
}
Return the registered handlers as an unmodifiable Map, with the registered path
as key and the handler object (or handler bean name in case of a lazy-init handler)
as value. |
public PathMatcher getPathMatcher() {
return this.pathMatcher;
}
Return the PathMatcher implementation to use for matching URL paths
against registered URL patterns. |
public Object getRootHandler() {
return this.rootHandler;
}
Return the root handler for this handler mapping (registered for "/"),
or null if none. |
protected Object lookupHandler(String urlPath,
HttpServletRequest request) throws Exception {
// Direct match?
Object handler = this.handlerMap.get(urlPath);
if (handler != null) {
validateHandler(handler, request);
return buildPathExposingHandler(handler, urlPath);
}
// Pattern match?
String bestPathMatch = null;
for (Iterator it = this.handlerMap.keySet().iterator(); it.hasNext();) {
String registeredPath = (String) it.next();
if (getPathMatcher().match(registeredPath, urlPath) &&
(bestPathMatch == null || bestPathMatch.length() < registeredPath.length())) {
bestPathMatch = registeredPath;
}
}
if (bestPathMatch != null) {
handler = this.handlerMap.get(bestPathMatch);
validateHandler(handler, request);
String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPathMatch, urlPath);
return buildPathExposingHandler(handler, pathWithinMapping);
}
// No handler found...
return null;
}
Look up a handler instance for the given URL path.
Supports direct matches, e.g. a registered "/test" matches "/test",
and various Ant-style pattern matches, e.g. a registered "/t*" matches
both "/test" and "/team". For details, see the AntPathMatcher class.
Looks for the most exact pattern, where most exact is defined as
the longest path pattern. |
protected void registerHandler(String[] urlPaths,
String beanName) throws IllegalStateException, BeansException {
Assert.notNull(urlPaths, "URL path array must not be null");
for (int j = 0; j < urlPaths.length; j++) {
registerHandler(urlPaths[j], beanName);
}
}
Register the specified handler for the given URL paths. |
protected void registerHandler(String urlPath,
Object handler) throws IllegalStateException, BeansException {
Assert.notNull(urlPath, "URL path must not be null");
Assert.notNull(handler, "Handler object must not be null");
Object resolvedHandler = handler;
// Eagerly resolve handler if referencing singleton via name.
if (!this.lazyInitHandlers && handler instanceof String) {
String handlerName = (String) handler;
if (getApplicationContext().isSingleton(handlerName)) {
resolvedHandler = getApplicationContext().getBean(handlerName);
}
}
Object mappedHandler = this.handlerMap.get(urlPath);
if (mappedHandler != null) {
if (mappedHandler != resolvedHandler) {
throw new IllegalStateException(
"Cannot map handler [" + handler + "] to URL path [" + urlPath +
"]: There is already handler [" + resolvedHandler + "] mapped.");
}
}
else {
if (urlPath.equals("/")) {
if (logger.isDebugEnabled()) {
logger.debug("Root mapping to handler [" + resolvedHandler + "]");
}
setRootHandler(resolvedHandler);
}
else if (urlPath.equals("/*")) {
if (logger.isDebugEnabled()) {
logger.debug("Default mapping to handler [" + resolvedHandler + "]");
}
setDefaultHandler(resolvedHandler);
}
else {
this.handlerMap.put(urlPath, resolvedHandler);
if (logger.isDebugEnabled()) {
logger.debug("Mapped URL path [" + urlPath + "] onto handler [" + resolvedHandler + "]");
}
}
}
}
Register the specified handler for the given URL path. |
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
}
Set if URL lookup should always use the full path within the current servlet
context. Else, the path within the current servlet mapping is used if applicable
(that is, in the case of a ".../*" servlet mapping in web.xml).
Default is "false". |
public void setLazyInitHandlers(boolean lazyInitHandlers) {
this.lazyInitHandlers = lazyInitHandlers;
}
Set whether to lazily initialize handlers. Only applicable to
singleton handlers, as prototypes are always lazily initialized.
Default is "false", as eager initialization allows for more efficiency
through referencing the controller objects directly.
If you want to allow your controllers to be lazily initialized,
make them "lazy-init" and set this flag to true. Just making them
"lazy-init" will not work, as they are initialized through the
references from the handler mapping in this case. |
public void setPathMatcher(PathMatcher pathMatcher) {
Assert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
}
Set the PathMatcher implementation to use for matching URL paths
against registered URL patterns. Default is AntPathMatcher. |
public void setRootHandler(Object rootHandler) {
this.rootHandler = rootHandler;
}
Set the root handler for this handler mapping, that is,
the handler to be registered for the root path ("/").
Default is null, indicating no root handler. |
public void setUrlDecode(boolean urlDecode) {
this.urlPathHelper.setUrlDecode(urlDecode);
}
Set if context path and request URI should be URL-decoded. Both are returned
undecoded by the Servlet API, in contrast to the servlet path.
Uses either the request encoding or the default encoding according
to the Servlet spec (ISO-8859-1). |
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
Assert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
}
Set the UrlPathHelper to use for resolution of lookup paths.
Use this to override the default UrlPathHelper with a custom subclass,
or to share common UrlPathHelper settings across multiple HandlerMappings
and MethodNameResolvers. |
protected void validateHandler(Object handler,
HttpServletRequest request) throws Exception {
}
Validate the given handler against the current request.
The default implementation is empty. Can be overridden in subclasses,
for example to enforce specific preconditions expressed in URL mappings. |