All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.web.servlet.handler.AbstractUrlHandlerMapping Maven / Gradle / Ivy

There is a newer version: 5.3.34
Show newest version
/*
 * Copyright 2002-2007 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.handler;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeansException;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.util.UrlPathHelper;

/**
 * Abstract base class for URL-mapped {@link org.springframework.web.servlet.HandlerMapping}
 * 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 * {@link org.springframework.util.AntPathMatcher 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. * * @author Juergen Hoeller * @since 16.04.2003 * @see #setAlwaysUseFullPath * @see #setUrlDecode * @see org.springframework.util.AntPathMatcher */ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping { private UrlPathHelper urlPathHelper = new UrlPathHelper(); private PathMatcher pathMatcher = new AntPathMatcher(); private Object rootHandler; private boolean lazyInitHandlers = false; private final Map handlerMap = new HashMap(); /** * 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". * @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath */ public void setAlwaysUseFullPath(boolean alwaysUseFullPath) { this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath); } /** * 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). *

Note: Setting this to "true" requires JDK 1.4 if the encoding differs * from the VM's platform default encoding, as JDK 1.3's URLDecoder class * does not offer a way to specify the encoding. * @see org.springframework.web.util.UrlPathHelper#setUrlDecode */ public void setUrlDecode(boolean urlDecode) { this.urlPathHelper.setUrlDecode(urlDecode); } /** * 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. * @see org.springframework.web.servlet.mvc.multiaction.AbstractUrlMethodNameResolver#setUrlPathHelper */ public void setUrlPathHelper(UrlPathHelper urlPathHelper) { this.urlPathHelper = urlPathHelper; } /** * Set the PathMatcher implementation to use for matching URL paths * against registered URL patterns. Default is AntPathMatcher. * @see org.springframework.util.AntPathMatcher */ public void setPathMatcher(PathMatcher pathMatcher) { Assert.notNull(pathMatcher, "PathMatcher must not be null"); this.pathMatcher = pathMatcher; } /** * 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 setRootHandler(Object rootHandler) { this.rootHandler = rootHandler; } /** * Return the root handler for this handler mapping (registered for "/"), * or null if none. */ public Object getRootHandler() { return this.rootHandler; } /** * 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 setLazyInitHandlers(boolean lazyInitHandlers) { this.lazyInitHandlers = lazyInitHandlers; } /** * Look up a handler for the URL path of the given request. * @param request current HTTP request * @return the handler instance, or null if none found */ 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. if ("/".equals(lookupPath)) { handler = getRootHandler(); } if (handler == null) { handler = getDefaultHandler(); } if (handler != null) { exposePathWithinMapping(lookupPath, request); } } return handler; } /** * 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. * @param urlPath URL the bean is mapped to * @param request current HTTP request (to expose the path within the mapping to) * @return the associated handler instance, or null if not found * @see #exposePathWithinMapping * @see org.springframework.util.AntPathMatcher */ protected Object lookupHandler(String urlPath, HttpServletRequest request) { // Direct match? Object handler = this.handlerMap.get(urlPath); if (handler != null) { exposePathWithinMapping(urlPath, request); return handler; } // Pattern match? String bestPathMatch = null; for (Iterator it = this.handlerMap.keySet().iterator(); it.hasNext();) { String registeredPath = (String) it.next(); if (this.pathMatcher.match(registeredPath, urlPath) && (bestPathMatch == null || bestPathMatch.length() <= registeredPath.length())) { bestPathMatch = registeredPath; } } if (bestPathMatch != null) { handler = this.handlerMap.get(bestPathMatch); exposePathWithinMapping(this.pathMatcher.extractPathWithinPattern(bestPathMatch, urlPath), request); } return handler; } /** * Expose the path within the current mapping as request attribute. * @param pathWithinMapping the path within the current mapping * @param request the request to expose the path to * @see #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE */ protected void exposePathWithinMapping(String pathWithinMapping, HttpServletRequest request) { request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping); } /** * Register the specified handler for the given URL paths. * @param urlPaths the URLs that the bean should be mapped to * @param beanName the name of the handler bean * @throws BeansException if the handler couldn't be registered * @throws IllegalStateException if there is a conflicting handler registered */ protected void registerHandler(String[] urlPaths, String beanName) throws BeansException, IllegalStateException { 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 path. * @param urlPath the URL the bean should be mapped to * @param handler the handler instance or handler bean name String * (a bean name will automatically be resolved into the corrresponding handler bean) * @throws BeansException if the handler couldn't be registered * @throws IllegalStateException if there is a conflicting handler registered */ protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException { Assert.notNull(urlPath, "URL path must not be null"); Assert.notNull(handler, "Handler object must not be null"); Object mappedHandler = this.handlerMap.get(urlPath); if (mappedHandler != null) { throw new IllegalStateException( "Cannot map handler [" + handler + "] to URL path [" + urlPath + "]: There is already handler [" + mappedHandler + "] mapped."); } // Eagerly resolve handler if referencing singleton via name. if (!this.lazyInitHandlers && handler instanceof String) { String handlerName = (String) handler; if (getApplicationContext().isSingleton(handlerName)) { handler = getApplicationContext().getBean(handlerName); } } if (urlPath.equals("/")) { if (logger.isDebugEnabled()) { logger.debug("Root mapping to handler [" + handler + "]"); } setRootHandler(handler); } else if (urlPath.equals("/*")) { if (logger.isDebugEnabled()) { logger.debug("Default mapping to handler [" + handler + "]"); } setDefaultHandler(handler); } else { this.handlerMap.put(urlPath, handler); if (logger.isDebugEnabled()) { logger.debug("Mapped URL path [" + urlPath + "] onto handler [" + handler + "]"); } } } /** * 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. * @see #getDefaultHandler() */ public final Map getHandlerMap() { return Collections.unmodifiableMap(this.handlerMap); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy