如何获取没有上下文路径的请求URI?


127

方法request.getRequestURI()返回带有上下文路径的URI。

例如,如果一个应用程序的基本网址http://localhost:8080/myapp/(即上下文路径是MYAPP),和我打电话request.getRequestURI()http://localhost:8080/myapp/secure/users,它将返回/myapp/secure/users

有什么办法可以让我们只获得这部分/secure/users,即没有上下文路径的URI?


Answers:


158

如果您位于映射在前缀模式上的前contoller servlet内,则可以使用HttpServletRequest#getPathInfo()

String pathInfo = request.getPathInfo();
// ...

假设您的示例中的servlet映射到/secure,则将返回/users该值,这将是典型的前端控制器servlet中唯一感兴趣的信息。

但是,如果Servlet映射到后缀模式(但是您的URL示例并未表明是这种情况),或者当您实际上位于过滤器中时(当尚未确定要调用的servlet时,因此getPathInfo()可能会返回null),那么最好的选择是使用上下文String方法自己根据上下文路径的长度对请求URI进行子字符串化:

HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
// ...

是否有理由使用它代替getServletPath()?我正在写一个过滤器,我注意到getPathInfo()return null,但是getServletPath()返回减去上下文的路径(适合传递给请求分派器)。
Jason C

@JasonC:回答是,getPathInfo()如果前端控制器servlet未映射在前缀模式上,则返回null。
BalusC

是的 我的意思是:有一个原因让您更喜欢getPathInfo而不是getServletPath吗?这里的许多其他高分答案也不使用getServletPath,这就是让我对此感到怀疑的原因,也是为什么我想知道的原因。我有一个正在处理的servlet项目,正在尝试完善自己的技能。
杰森C

1
@JasonC:当您安装了基于Servlet的MVC框架(如JSF或Spring MVC)时,servlet路径可能会更改。然后,它将代表MVC框架的内部路径(例如/foo.xhtml而不是/foo.jsf),而不是实际的请求URI(最终用户将在浏览器的地址栏中看到该路径)。在这种情况下,原始servlet路径可以作为带有key的request属性来解析RequestDispatcher.FORWARD_SERVLET_PATH。无论如何,该问题都会明确要求输入请求URI(例如在浏览器的地址栏中),因此答案就以此为基础。
BalusC

74
request.getRequestURI().substring(request.getContextPath().length())

太棒了!这正是我在寻找的东西。
工匠

4
+1我认为这比getPathInfo更好,因为getPathInfo可以为null和其他奇数。各种Spring代码都执行getContextPath并将其从URI中删除,就像您所做的一样,而不是getPathInfo。
亚当·根特


14

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());
    ...

}

8

如果在Filter中使用request.getPathInfo(),则似乎总是会得到null(至少对于jetty而言)。

这个简短的无效Bug +响应暗示了我认为的问题:

https://issues.apache.org/bugzilla/show_bug.cgi?id=28323

我怀疑这与在servlet获得请求之前运行筛选器有关。这可能是容器错误,或者是我无法识别的预期行为。

尽管contextPath可用,所以fforws解决方案甚至可以在过滤器中使用。我不喜欢手动操作,但是实现失败或


5

一种方法是从请求URI保留servelet上下文路径。

String p = request.getRequestURI();
String cp = getServletContext().getContextPath();

if (p.startsWith(cp)) {
  String.err.println(p.substring(cp.length());
}

在这里阅读。


-1

也许您可以使用split方法来消除“ / myapp”,例如:

string[] uris=request.getRequestURI().split("/");
string uri="/"+uri[1]+"/"+uris[2];

3
如果我以根用户身份部署应用程序,并且其基本URL变为localhost:8080,这将导致问题。在这种情况下,request.getRequestURI()将返回“ / secure / user”,并且您的split方法将在此处引起问题。该代码不应依赖于部署。
工匠
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.