request.getRequestURI()方法会返回带有上下文路径的 URI。
例如,如果应用程序的基础URL是http://localhost:8080/myapp/
(即上下文路径为myapp),且我对http://localhost:8080/myapp/secure/users
调用request.getRequestURI()
,它将返回/myapp/secure/users
。
是否有办法仅获取此部分/secure/users
,即不带上下文路径的 URI?
request.getRequestURI()方法会返回带有上下文路径的 URI。
例如,如果应用程序的基础URL是http://localhost:8080/myapp/
(即上下文路径为myapp),且我对http://localhost:8080/myapp/secure/users
调用request.getRequestURI()
,它将返回/myapp/secure/users
。
是否有办法仅获取此部分/secure/users
,即不带上下文路径的 URI?
如果你在一个前端控制器Servlet中,它被映射到类似/foo/*
的前缀模式上,那么你可以直接使用HttpServletRequest#getPathInfo()
方法。
String pathInfo = request.getPathInfo();
// ...
假设你的示例中的servlet映射为/secure/*
,那么这将返回/users
,它将是典型前端控制器servlet中唯一感兴趣的信息。*.foo
(但您的URL示例并未表明这种情况),或者当您实际上在过滤器中时(当要调用的servlet尚未确定时,因此getPathInfo()
可能会返回null
),则最好根据上下文路径的长度自己截取请求URI,使用通常的String
方法:HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
// ...
getServletPath()
是否有原因?我正在编写一个过滤器,发现getPathInfo()
返回null
,但是getServletPath()
返回路径减去上下文(适合传递给请求分派器)。 - Jason CgetPathInfo()
会返回null。 - BalusC/foo.xhtml
而不是/foo.jsf
),而不是实际请求URI(即最终用户在浏览器地址栏中看到的URI)。在这种情况下,原始servlet路径可以作为请求属性使用,键为RequestDispatcher.FORWARD_SERVLET_PATH
。无论如何,问题明确要求请求URI(就像浏览器地址栏中的URI),因此答案基于此。 - BalusCrequest.getRequestURI().substring(request.getContextPath().length())
使用Spring,您可以完成以下操作:
String path = new UrlPathHelper().getPathWithinApplication(request);
有时候getPathInfo()会返回null。在HttpServletRequest的文档中,有这样一段话:
如果没有额外的路径信息,此方法将返回null。
在过滤器中,我需要获取不包含上下文路径的文件路径,但是getPathInfo() 返回了null。所以我使用另一种方法:httpRequest.getServletPath()
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String newPath = parsePathToFile(httpRequest.getServletPath());
...
}
https://issues.apache.org/bugzilla/show_bug.cgi?id=28323
我怀疑这与过滤器在servlet收到请求之前运行有关。这可能是容器错误,或者是我无法识别的预期行为。String p = request.getRequestURI();
String cp = getServletContext().getContextPath();
if (p.startsWith(cp)) {
String.err.println(p.substring(cp.length());
}
在这里阅读相关信息。
String requestUriWithinApp = req.getPathInfo() == null
? req.getServletPath()
: req.getServletPath() + req.getPathInfo();
ServletPath
获取调用servlet的URL部分。而PathInfo
返回与客户端发送的URL关联的任何额外路径信息。根据客户端使用的URL,PathInfo
可能为空。StringBuilder sb = new StringBuilder();
sb.append(req.getServletPath());
if (req.getPathInfo() != null) {
sb.append(req.getPathInfo());
}
if (req.getQueryString() != null) {
sb.append("?").append(req.getQueryString());
}
请求URI的公式如下:
requestURI = contextPath + servletPath + pathInfo
根据您的问题,您不想使用contextPath
,所以您只需要:
servletPath + pathInfo
例如,如果您有:
/catalog
的Web应用上下文和/garden/*
的GardenServlet
以及/catalog/lawn/index.html
pathInfo
就是/index.html
这个例子在Servlet规范-3.6请求路径元素中有更详细的描述。
Tuckey's UrlRewriteFilter的文档中包含了一个更完整的示例,展示了在ServletRequest中如何组成URL。 // http://hostname.com:80/mywebapp/servlet/MyServlet/a/b;c=123?d=789
public static String getUrl(HttpServletRequest req) {
String scheme = req.getScheme(); // http
String serverName = req.getServerName(); // hostname.com
int serverPort = req.getServerPort(); // 80
String contextPath = req.getContextPath(); // /mywebapp
String servletPath = req.getServletPath(); // /servlet/MyServlet
String pathInfo = req.getPathInfo(); // /a/b;c=123
String queryString = req.getQueryString(); // d=789
// Reconstruct original requesting URL
String url = scheme + "://" + serverName + ":" + serverPort + contextPath + servletPath;
if (pathInfo != null) {
url += pathInfo;
}
if (queryString != null) {
url += "?" + queryString;
}
return url;
}
string[] uris=request.getRequestURI().split("/");
string uri="/"+uri[1]+"/"+uris[2];