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

org.springframework.web.util.UrlPathHelper Maven / Gradle / Ivy

/*
 * Copyright 2002-2005 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.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.core.JdkVersion;
import org.springframework.util.StringUtils;

/**
 * Helper class for URL path matching. Provides support for URL paths
 * in RequestDispatcher includes, and support for URL decoding.
 *
 * 

Used by AbstractUrlHandlerMapping, AbstractUrlMethodNameResolver * and RequestContext for path matching and/or URI determination. * * @author Juergen Hoeller * @since 14.01.2004 * @see org.springframework.web.servlet.handler.AbstractUrlHandlerMapping * @see org.springframework.web.servlet.mvc.multiaction.AbstractUrlMethodNameResolver * @see org.springframework.web.servlet.support.RequestContext */ public class UrlPathHelper { /** * Standard Servlet spec request attributes for include URI and paths. *

If included via a RequestDispatcher, the current resource will see the * original request. Its own URI and paths are exposed as request attributes. */ public static final String INCLUDE_URI_REQUEST_ATTRIBUTE = "javax.servlet.include.request_uri"; public static final String INCLUDE_CONTEXT_PATH_REQUEST_ATTRIBUTE = "javax.servlet.include.context_path"; public static final String INCLUDE_SERVLET_PATH_REQUEST_ATTRIBUTE = "javax.servlet.include.servlet_path"; private final Log logger = LogFactory.getLog(getClass()); private boolean alwaysUseFullPath = false; private boolean urlDecode = false; private String defaultEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING; /** * Set if URL lookup should always use full path within current servlet * context. Else, the path within the current servlet mapping is used * if applicable (i.e. in the case of a ".../*" servlet mapping in web.xml). * Default is false. */ public void setAlwaysUseFullPath(boolean alwaysUseFullPath) { this.alwaysUseFullPath = 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 #getServletPath * @see #getContextPath * @see #getRequestUri * @see WebUtils#DEFAULT_CHARACTER_ENCODING * @see javax.servlet.ServletRequest#getCharacterEncoding * @see java.net.URLDecoder#decode(String, String) * @see java.net.URLDecoder#decode(String) */ public void setUrlDecode(boolean urlDecode) { this.urlDecode = urlDecode; } /** * Set the default character encoding to use for URL decoding. * Default is ISO-8859-1, according to the Servlet spec. *

If the request specifies a character encoding itself, the request * encoding will override this setting. This also allows for generically * overriding the character encoding in a filter that invokes the * ServletRequest.setCharacterEncoding method. * @param defaultEncoding the character encoding to use * @see #determineEncoding * @see javax.servlet.ServletRequest#getCharacterEncoding * @see javax.servlet.ServletRequest#setCharacterEncoding * @see WebUtils#DEFAULT_CHARACTER_ENCODING */ public void setDefaultEncoding(String defaultEncoding) { this.defaultEncoding = defaultEncoding; } /** * Return the default character encoding to use for URL decoding. */ protected String getDefaultEncoding() { return defaultEncoding; } /** * Return the mapping lookup path for the given request, within the current * servlet mapping if applicable, else within the web application. *

Regards include request URL if called within a RequestDispatcher include. * @param request current HTTP request * @return the lookup path * @see #getPathWithinApplication * @see #getPathWithinServletMapping */ public String getLookupPathForRequest(HttpServletRequest request) { // Always use full path within current servlet context? if (this.alwaysUseFullPath) { return getPathWithinApplication(request); } // Else, use path within current servlet mapping if applicable String rest = getPathWithinServletMapping(request); if (!"".equals(rest)) { return rest; } else { return getPathWithinApplication(request); } } /** * Return the path within the servlet mapping for the given request, * i.e. the part of the request's URL beyond the part that called the servlet, * or "" if the whole URL has been used to identify the servlet. *

Regards include request URL if called within a RequestDispatcher include. *

E.g.: servlet mapping = "/test/*"; request URI = "/test/a" -> "/a". *

E.g.: servlet mapping = "/test"; request URI = "/test" -> "". *

E.g.: servlet mapping = "/*.test"; request URI = "/a.test" -> "". * @param request current HTTP request * @return the path within the servlet mapping, or "" */ public String getPathWithinServletMapping(HttpServletRequest request) { String pathWithinApp = getPathWithinApplication(request); String servletPath = getServletPath(request); if (pathWithinApp.startsWith(servletPath)) { // Normal case: URI contains servlet path. return pathWithinApp.substring(servletPath.length()); } else { // Special case: URI is different from servlet path. // Can happen e.g. with index page: URI="/", servletPath="/index.html" // Use servlet path in this case, as it indicates the actual target path. return servletPath; } } /** * Return the path within the web application for the given request. *

Regards include request URL if called within a RequestDispatcher include. * @param request current HTTP request * @return the path within the web application */ public String getPathWithinApplication(HttpServletRequest request) { String contextPath = getContextPath(request); String requestUri = getRequestUri(request); if (StringUtils.startsWithIgnoreCase(requestUri, contextPath)) { // Normal case: URI contains context path. return requestUri.substring(contextPath.length()); } else { // Special case: rather unusual. return requestUri; } } /** * Return the servlet path for the given request, regarding an include request * URL if called within a RequestDispatcher include. *

As the value returned by request.getServletPath() is already decoded by * the servlet container, this method will not attempt to decode it. * @param request current HTTP request * @return the servlet path */ public String getServletPath(HttpServletRequest request) { String servletPath = (String) request.getAttribute(INCLUDE_SERVLET_PATH_REQUEST_ATTRIBUTE); if (servletPath == null) { servletPath = request.getServletPath(); } return servletPath; } /** * Return the context path for the given request, regarding an include request * URL if called within a RequestDispatcher include. *

As the value returned by request.getContextPath() is not decoded by * the servlet container, this method will decode it. * @param request current HTTP request * @return the context path */ public String getContextPath(HttpServletRequest request) { String contextPath = (String) request.getAttribute(INCLUDE_CONTEXT_PATH_REQUEST_ATTRIBUTE); if (contextPath == null) { contextPath = request.getContextPath(); } return decodeRequestString(request, contextPath); } /** * Return the request URI for the given request, regarding an include request * URL if called within a RequestDispatcher include. *

As the value returned by request.getRequestURI() is not decoded by * the servlet container, this method will decode it. *

The URI that the web container resolves should be correct, but some * containers like JBoss/Jetty incorrectly include ";" strings like ";jsessionid" * in the URI. This method cuts off such incorrect appendices. * @param request current HTTP request * @return the request URI */ public String getRequestUri(HttpServletRequest request) { String uri = (String) request.getAttribute(INCLUDE_URI_REQUEST_ATTRIBUTE); if (uri == null) { uri = request.getRequestURI(); } uri = decodeRequestString(request, uri); int semicolonIndex = uri.indexOf(';'); return (semicolonIndex != -1 ? uri.substring(0, semicolonIndex) : uri); } /** * Decode the given source string with a URLEncoder. The encoding will be taken * from the request, falling back to the default "ISO-8859-1". * @param request current HTTP request * @param source the String to decode * @return the decoded String * @see WebUtils#DEFAULT_CHARACTER_ENCODING * @see javax.servlet.ServletRequest#getCharacterEncoding * @see java.net.URLDecoder */ public String decodeRequestString(HttpServletRequest request, String source) { if (this.urlDecode) { String enc = determineEncoding(request); try { if (JdkVersion.getMajorJavaVersion() < JdkVersion.JAVA_14) { throw new UnsupportedEncodingException("JDK URLDecoder does not support custom encoding"); } return URLDecoder.decode(source, enc); } catch (UnsupportedEncodingException ex) { if (logger.isWarnEnabled()) { logger.warn("Could not decode request string [" + source + "] with encoding '" + enc + "': falling back to platform default encoding; exception message: " + ex.getMessage()); } return URLDecoder.decode(source); } } return source; } /** * Determine the encoding for the given request. * Can be overridden in subclasses. *

The default implementation checks the request encoding, * falling back to the default encoding specified for this resolver. * @param request current HTTP request * @return the encoding for the request (never null) * @see javax.servlet.ServletRequest#getCharacterEncoding * @see #setDefaultEncoding */ protected String determineEncoding(HttpServletRequest request) { String enc = request.getCharacterEncoding(); if (enc == null) { enc = this.defaultEncoding; } return enc; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy