HttpServletRequest中的getRequestURI和getPathInfo方法之间有什么区别?


143

我正在制作一个简单,非常轻便的前控制器。我需要将请求路径匹配到不同的处理程序(操作),以便选择正确的处理程序。

在我的本地计算机上HttpServletRequest.getPathInfo()HttpServletRequest.getRequestURI()返回相同的结果。但是我不确定他们将在生产环境中返回什么。

那么,这些方法有什么区别,我应该选择什么?


1
您可能会发现此答案也很有用。
BalusC

@BalusC:谢谢,我已经在使用该答案中的一些技巧。
罗马

这用一个很好的图表解释了这种区别:agiletribe.wordpress.com/2016/02/23/…–
AgilePro

Answers:


77

getPathInfo()给出URI后面的额外路径信息,用于访问Servlet,其中getRequestURI()给出完整的URI。

我本以为它们会有所不同,因为首先必须为Servlet配置自己的URI模式。我认为我从来没有从根(/)服务过Servlet。

例如,如果Servlet'Foo'被映射到URI'/ foo',那么我会想到URI:

/foo/path/to/resource

将导致:

RequestURI = /foo/path/to/resource

PathInfo = /path/to/resource

20
值得一提的解码行为。getRequestURI()不会解码字符串。getPathInfo()在哪里解码。
Kavindu Dodanduwa '16

1
在某些情况下,getRequestURI()给我的字符串"/foo/path/to/resource"作为预期,但getPathInfo()对同一HttpServletRequest对象给我null。到底是怎么回事?编辑:下面由用户“ 30thh”回答。
anddero

460

我将在此处放置一个小的比较表(只是将其放在某处):

Servlet映射为/test%3F/*,应用程序部署在下/app

http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S%3F+ID?p+1=c+d&p+2=e+f#a

Method              URL-Decoded Result           
----------------------------------------------------
getContextPath()        no      /app
getLocalAddr()                  127.0.0.1
getLocalName()                  30thh.loc
getLocalPort()                  8480
getMethod()                     GET
getPathInfo()           yes     /a?+b
getProtocol()                   HTTP/1.1
getQueryString()        no      p+1=c+d&p+2=e+f
getRequestedSessionId() no      S%3F+ID
getRequestURI()         no      /app/test%3F/a%3F+b;jsessionid=S+ID
getRequestURL()         no      http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S+ID
getScheme()                     http
getServerName()                 30thh.loc
getServerPort()                 8480
getServletPath()        yes     /test?
getParameterNames()     yes     [p 2, p 1]
getParameter("p 1")     yes     c d

在上面的示例中,服务器正在上运行,localhost:8480并且名称30thh.loc已放入OS hosts文件中。

注释

  • “ +”仅在查询字符串中被视为空格

  • 锚“ #a”未传输到服务器。只有浏览器可以使用它。

  • 如果url-patternservlet映射中的不以结尾*(例如/test*.jsp),则getPathInfo()返回null

如果使用Spring MVC

  • 方法getPathInfo()返回null

  • 方法getServletPath()返回上下文路径和会话ID之间的部分。在上面的示例中,该值为/test?/a?+b

  • 小心的URL编码的部分@RequestMapping@RequestParam在春季。它存在错误(当前版本3.2.4),通常无法按预期工作


20
我正在打印您的答案,并将其作为海报张贴在我们的办公室。那是多么有用!
Ibrahim Arief 2015年

2
If the url-pattern in the servlet mapping does not end with * (for example /test or *.jsp), getPathInfo() returns null.辉煌。
鲍里斯·特鲁霍夫

1
相信无论是getRequestURI()getRequestURL()应该返回未解码的jsessionid,在这种情况下S%3F+ID。至少它在Tomcat / 8.5.6上执行。
Gediminas Rimsa'1

29

让我们分解一下客户端将在其地址栏中键入以到达您的servlet的完整URL:

http://www.example.com:80/awesome-application/path/to/servlet/path/info?a=1&b=2#boo

这些部分是:

  1. 方案: http
  2. 主机名: www.example.com
  3. 港口: 80
  4. 上下文路径: awesome-application
  5. servlet路径: path/to/servlet
  6. 路径信息: path/info
  7. 查询: a=1&b=2
  8. 分段: boo

请求URI(由getRequestURI返回)对应于第4、5和6部分。

(顺便说一句,即使您不要求这样做,方法getRequestURL也会为您提供第1、2、3、4、5和6部分)。

现在:

  • 第4部分(上下文路径)用于从服务器中可能运行的许多其他应用程序中选择特定的应用程序
  • 第5部分(servlet路径)用于从可能捆绑在应用程序的WAR中的许多其他servlet中选择特定的servlet
  • 第6部分(路径信息)由servlet的逻辑解释(例如,它可能指向由servlet控制的某些资源)。
  • 使用getQueryString,第7部分(查询)也可用于您的servlet
  • 第8部分(片段)甚至没有发送到服务器,并且是相关的,仅客户端知道

以下内容始终有效(URL编码差异除外):

requestURI = contextPath + servletPath + pathInfo

Servlet 3.0规范中的以下示例非常有用:


注意:图片如下,我没有时间在HTML中重新创建:

在此处输入图片说明


16

考虑以下servlet conf:

   <servlet>
        <servlet-name>NewServlet</servlet-name>
        <servlet-class>NewServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>NewServlet</servlet-name>
        <url-pattern>/NewServlet/*</url-pattern>
    </servlet-mapping>

现在,当我点击URL时http://localhost:8084/JSPTemp1/NewServlet/jhi,它将NewServlet以上述模式映射时调用。

这里:

getRequestURI() =  /JSPTemp1/NewServlet/jhi
getPathInfo() = /jhi

我们有那些:

  • getPathInfo()

    返回
    一个字符串,该字符串由Web容器解码,并指定在servlet路径之后但在请求URL中的查询字符串之前的其他路径信息;如果URL没有任何额外的路径信息,则返回null

  • getRequestURI()

    返回
    一个字符串,其中包含从协议名称到查询字符串的URL的一部分

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.