繁体   English   中英

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

[英]What's the difference between getRequestURI and getPathInfo methods in HttpServletRequest?

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

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

那么,这些方法和我应该选择什么之间的区别是什么?

我会在这里放一个小的比较表(只是为了让它在某处):

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”未传输到服务器。 只有浏览器可以使用它。

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

如果使用Spring MVC

  • 方法getPathInfo()返回null

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

  • 在Spring中要小心@RequestMapping@RequestParam URL编码部分。 它是错误的(当前版本3.2.4)并且通常不按预期工作

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

让我们分解客户端在其地址栏中键入的完整URL以访问您的servlet:

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路径)用于从许多其他servlet中选择一个特定的servlet,这些servlet可能捆绑在应用程序的WAR中
  • 第6部分(路径信息)由servlet的逻辑解释(例如,它可能指向由servlet控制的某些资源)。
  • 第7部分(查询)也可以使用getQueryString提供给您的servlet
  • 第8部分(片段)甚至没有发送到服务器,只与客户端相关且只知道

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

requestURI = contextPath + servletPath + pathInfo

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


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

在此输入图像描述

考虑以下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()

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM