DispatcherServlet 匹配请求路径时的疑惑
存在Servlet A,其url-pattern为 /A/*,则形如/A,/A/bcd,/A/b/c/d等式样的请求全部能够被Servlet A匹配上。
但是SpringMVC的DispatcherServlet的url-pattern /A/*只能匹配上/A式样的请求,/A/abc,/A/b/c等式样的均匹配不上。
debug发现,org.springframework.web.util.UrlPathHelper.getPathWithinServletMapping()方法会将请求路径中与url-pattern配置一致的路径(servletPath)截去,然后用剩下的部分去匹配,不知这么做的用意是什么,还请各位不吝赐教
/** * 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. * <p>Detects include request URL if called within a RequestDispatcher include. * <p>E.g.: servlet mapping = "/*"; request URI = "/test/a" -> "/test/a". * <p>E.g.: servlet mapping = "/"; request URI = "/test/a" -> "/test/a". * <p>E.g.: servlet mapping = "/test/*"; request URI = "/test/a" -> "/a". * <p>E.g.: servlet mapping = "/test"; request URI = "/test" -> "". * <p>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); String sanitizedPathWithinApp = getSanitizedPath(pathWithinApp); String path; // 不能理解此处的用意何在 // If the app container sanitized the servletPath, check against the sanitized version if (servletPath.contains(sanitizedPathWithinApp)) { path = getRemainingPath(sanitizedPathWithinApp, servletPath, false); } else { path = getRemainingPath(pathWithinApp, servletPath, false); } if (path != null) { // Normal case: URI contains servlet path. return path; } else { // Special case: URI is different from servlet path. String pathInfo = request.getPathInfo(); if (pathInfo != null) { // Use path info if available. Indicates index page within a servlet mapping? // e.g. with index page: URI="/", servletPath="/index.html" return pathInfo; } if (!this.urlDecode) { // No path info... (not mapped by prefix, nor by extension, nor "/*") // For the default servlet mapping (i.e. "/"), urlDecode=false can // cause issues since getServletPath() returns a decoded path. // If decoding pathWithinApp yields a match just use pathWithinApp. path = getRemainingPath(decodeInternal(request, pathWithinApp), servletPath, false); if (path != null) { return pathWithinApp; } } // Otherwise, use the full servlet path. return servletPath; } }