方法 request.getRequestURI() 返回带有上下文路径的 URI。
例如,如果应用程序的基本 URL 是
http://localhost:8080/myapp/
(即上下文路径是 myapp),并且我为 request.getRequestURI()
调用 http://localhost:8080/myapp/secure/users
,它将返回 /myapp/secure/users
。
有什么办法我们可以只获取这部分
/secure/users
,即没有上下文路径的URI?
如果您位于映射到前缀模式(例如
/foo/*
)的前端控制器 servlet 中,那么您可以只使用 HttpServletRequest#getPathInfo()
。
String pathInfo = request.getPathInfo();
// ...
假设示例中的 servlet 映射到
/secure/*
,那么这将返回 /users
,这将是典型前端控制器 servlet 中唯一感兴趣的信息。
但是,如果 servlet 映射到后缀模式,例如
*.foo
(但是您的 URL 示例并不表明情况如此),或者当您实际上位于过滤器内时(当要调用的 servlet 是尚未确定,因此 getPathInfo()
可能会返回 null
),那么最好的选择是使用通常的 String
方法,根据上下文路径的长度自行对请求 URI 进行子字符串化:
HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
// ...
request.getRequestURI().substring(request.getContextPath().length())
使用 Spring 你可以做到:
String path = new UrlPathHelper().getPathWithinApplication(request);
getPathInfo() 有时返回 null。在文档中HttpServletRequest
如果没有额外的路径信息,该方法返回null。
我需要在 Filter 中获取没有上下文路径的文件路径,并且 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());
...
}
如果你在 Filter 中使用 request.getPathInfo() ,你似乎总是得到 null (至少对于 jetty 来说是这样)。
这个简洁的无效错误+响应暗示了我认为的问题:
https://issues.apache.org/bugzilla/show_bug.cgi?id=28323
我怀疑这与过滤器在 servlet 获取请求之前运行这一事实有关。这可能是一个容器错误,或者是我无法识别的预期行为。
尽管 contextPath 可用,所以 fforws 解决方案即使在过滤器中也能工作。我不喜欢手动完成,但实现已损坏或
实现此目的的一种方法是从请求 URI 中恢复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 关联的任何额外路径信息。 PathInfo
可能为 null,具体取决于客户端使用的 URL。
为了获得更完整的 URI,您还可以包含查询字符串。然后你可以使用:
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());
}
requestURI的公式为:
requestURI = contextPath + servletPath + 路径信息
在你的问题中,你不想使用
contextPath
,所以你需要:
servletPath + 路径信息
例如,如果您有:
/catalog
和 GardenServlet
表示图案 /garden/*
和 /catalog/lawn/index.html
pathInfo
就是 /index.html
此示例在 Servlet 规范 - 3.6 请求路径元素中进行了更详细的描述。
Tuckey 的 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];