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

busg9geu  于 2023-10-14  发布在  Java
关注(0)|答案(8)|浏览(172)

方法request.getRequestURI()返回带有上下文路径的URI。
例如,如果应用程序的基本URL是http://localhost:8080/myapp/(即上下文路径是myapp),我调用request.getRequestURI()来获取http://localhost:8080/myapp/secure/users,它将返回/myapp/secure/users
我们有没有办法只得到这部分/secure/users,即没有上下文路径的URI?

3bygqnnd

3bygqnnd1#

如果你在一个Map到前缀模式(如/foo/*)的前端控制器servlet中,那么你可以只使用HttpServletRequest#getPathInfo()

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

假设示例中的servletMap到/secure/*上,那么这将返回/users,这将是典型前端控制器servlet中唯一感兴趣的信息。
但是,如果servletMap到后缀模式(如*.foo),(你的URL示例并不表明是这种情况),或者当你实际上是在一个过滤器(当还没有确定要调用的servlet时,因此getPathInfo()可以返回null),那么你最好的办法是根据上下文路径的长度,使用通常的String方法,自己对请求URI进行子串化:

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

pu3pd22g2#

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

olhwl3o23#

使用Spring,您可以:

String path = new UrlPathHelper().getPathWithinApplication(request);
kyvafyod

kyvafyod4#

getPathInfo()有时返回null。在文档中
如果没有额外的路径信息,此方法将返回null。
我需要在Filter中获取没有上下文路径的文件路径,getPathInfo()返回null。所以我用另一种方法: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());
    ...

}
np8igboo

np8igboo5#

如果在Filter中使用request.getPathInfo(),似乎总是得到null(至少在jetty中是这样)。
这个简短的无效bug +响应暗示了我认为的问题:
https://issues.apache.org/bugzilla/show_bug.cgi?id=28323
我怀疑这与过滤器在servlet获得请求之前运行的事实有关。这可能是一个容器错误,或者是我无法识别的预期行为。
contextPath是可用的,所以fforws解决方案即使在过滤器中也可以工作。我不喜欢用手来做,但是实现被破坏了,或者

0yg35tkg

0yg35tkg6#

一种方法是从请求URI中获取servelet上下文路径。

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

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

在这里阅读。

jdgnovmf

jdgnovmf7#

简短回答

String requestUriWithinApp = req.getPathInfo() == null
        ? req.getServletPath()
        : req.getServletPath() + req.getPathInfo();

ServletPath获取调用servlet的URL部分。PathInfo返回与客户端发出此请求时发送的URL相关联的任何额外路径信息。PathInfo可能为null,具体取决于客户端使用的URL。
对于更完整的URI,您还可以包含queryString。然后您可以使用:用途:

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 + pathInfo
在你的问题中,你不想使用contextPath,所以你需要:
servletPath + pathInfo
例如,如果您有:

  • /catalog上的webapp上下文,
  • 一个GardenServlet,用于图案/garden/*,以及
  • 客户端发送的/catalog/lawn/index.html请求
  • 然后pathInfo/index.html

这个例子在Servlet Specification - 3.6 Request Path Elements中有更详细的描述。
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;
    }
dwbf0jvd

dwbf0jvd8#

也许你可以使用split方法来消除'/myapp',例如:

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

相关问题