简体   繁体   English

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

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

I'm making a simple, very lightweight front-controller. 我正在制作一个简单,非常轻巧的前置控制器。 I need to match request paths to different handlers (actions) in order to choose the correct one. 我需要将请求路径与不同的处理程序(操作)匹配,以便选择正确的路径。

On my local machine HttpServletRequest.getPathInfo() and HttpServletRequest.getRequestURI() return the same results. 在我的本地机器上HttpServletRequest.getPathInfo()HttpServletRequest.getRequestURI()返回相同的结果。 But I'm not sure what will they return in the production environment. 但我不确定它们会在生产环境中返回什么。

So, what's the difference between these method and what should I choose? 那么,这些方法和我应该选择什么之间的区别是什么?

I will put a small comparison table here (just to have it somewhere): 我会在这里放一个小的比较表(只是为了让它在某处):

Servlet is mapped as /test%3F/* and the application is deployed under /app . 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

In the example above the server is running on the localhost:8480 and the name 30thh.loc was put into OS hosts file. 在上面的示例中,服务器在localhost:8480上运行,名称30thh.loc被放入OS hosts文件中。

Comments 评论

  • "+" is handled as space only in the query string “+”仅在查询字符串中作为空格处理

  • Anchor "#a" is not transferred to the server. 锚“#a”未传输到服务器。 Only the browser can work with it. 只有浏览器可以使用它。

  • If the url-pattern in the servlet mapping does not end with * (for example /test or *.jsp ), getPathInfo() returns null . 如果servlet映射中的url-pattern不以*结尾(例如/test*.jsp ),则getPathInfo()将返回null

If Spring MVC is used 如果使用Spring MVC

  • Method getPathInfo() returns null . 方法getPathInfo()返回null

  • Method getServletPath() returns the part between the context path and the session ID. 方法getServletPath()返回上下文路径和会话ID之间的部分。 In the example above the value would be /test?/a?+b 在上面的例子中,值是/test?/a?+b

  • Be careful with URL encoded parts of @RequestMapping and @RequestParam in Spring. 在Spring中要小心@RequestMapping@RequestParam URL编码部分。 It is buggy (current version 3.2.4) and is usually not working as expected . 它是错误的(当前版本3.2.4)并且通常不按预期工作

getPathInfo() gives the extra path information after the URI, used to access your Servlet, where as getRequestURI() gives the complete URI. getPathInfo()在URI之后提供额外的路径信息,用于访问您的Servlet,其中getRequestURI()提供完整的URI。

I would have thought they would be different, given a Servlet must be configured with its own URI pattern in the first place; 我认为它们会有所不同,因为Servlet必须首先配置自己的URI模式; I don't think I've ever served a Servlet from root (/). 我不认为我曾经从根(/)服务过Servlet。

For example if Servlet 'Foo' is mapped to URI '/foo' then I would have thought the URI: 例如,如果Servlet'Foo'映射到URI'/ foo',那么我会想到URI:

/foo/path/to/resource

Would result in: 会导致:

RequestURI = /foo/path/to/resource

and

PathInfo = /path/to/resource

Let's break down the full URL that a client would type into their address bar to reach your servlet: 让我们分解客户端在其地址栏中键入的完整URL以访问您的servlet:

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

The parts are: 部分是:

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

The request URI (returned by getRequestURI ) corresponds to parts 4, 5 and 6. 请求URI(由getRequestURI返回)对应于第4,5和6部分。

(incidentally, even though you're not asking for this, the method getRequestURL would give you parts 1, 2, 3, 4, 5 and 6). (顺便说一句,即使你没有要求这个,方法getRequestURL会给你第1,2,3,4,5和6部分)。

Now: 现在:

  • part 4 (the context path) is used to select your particular application out of many other applications that may be running in the server 第4部分(上下文路径)用于从服务器中可能运行的许多其他应用程序中选择您的特定应用程序
  • part 5 (the servlet path) is used to select a particular servlet out of many other servlets that may be bundled in your application's WAR 第5部分(servlet路径)用于从许多其他servlet中选择一个特定的servlet,这些servlet可能捆绑在应用程序的WAR中
  • part 6 (the path info) is interpreted by your servlet's logic (eg it may point to some resource controlled by your servlet). 第6部分(路径信息)由servlet的逻辑解释(例如,它可能指向由servlet控制的某些资源)。
  • part 7 (the query) is also made available to your servlet using getQueryString 第7部分(查询)也可以使用getQueryString提供给您的servlet
  • part 8 (the fragment) is not even sent to the server and is relevant and known only to the client 第8部分(片段)甚至没有发送到服务器,只与客户端相关且只知道

The following always holds (except for URL encoding differences): 以下内容始终成立(URL编码差异除外):

requestURI = contextPath + servletPath + pathInfo

The following example from the Servlet 3.0 specification is very helpful: Servlet 3.0规范中的以下示例非常有用:


Note: image follows, I don't have the time to recreate in HTML: 注意:图片如下,我没有时间在HTML中重新创建:

在此输入图像描述

Consider the following servlet conf: 考虑以下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>

Now, when I hit the URL http://localhost:8084/JSPTemp1/NewServlet/jhi , it will invoke NewServlet as it is mapped with the pattern described above. 现在,当我点击URL http://localhost:8084/JSPTemp1/NewServlet/jhi ,它将调用NewServlet因为它使用上述模式进行映射。

Here: 这里:

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

We have those ones: 我们有那些:

  • getPathInfo()

    returns 回报
    a String, decoded by the web container, specifying extra path information that comes after the servlet path but before the query string in the request URL; 一个字符串,由Web容器解码,指定在servlet路径之后但在请求URL中的查询字符串之前的额外路径信息; or null if the URL does not have any extra path information 如果URL没有任何额外的路径信息,则返回null

  • getRequestURI()

    returns 回报
    a String containing the part of the URL from the protocol name up to the query string 一个String,包含从协议名称到查询字符串的URL部分

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

相关问题 SpringBoot中的HttpServletRequest getRequestURI - HttpServletRequest getRequestURI in SpringBoot Java中的块和方法有什么区别? - What's the difference between blocks and methods in Java? “configure”和“configureGlobal”方法有什么区别? - What's the difference between 'configure' and 'configureGlobal' methods? 这两种通用方法有什么区别? - What's difference between these two generic methods? Calendar 的 getActualMinimum 和 getGreatestMinimum 方法有什么区别? - What's the difference between Calendar's getActualMinimum and getGreatestMinimum methods? EasyMock 的.andReturn 和.andAnswer 方法有什么区别? - What's the difference between EasyMock's .andReturn and .andAnswer methods? servlet中的findAttribute()和getAttribute()方法有什么区别? - What's the difference between the methods findAttribute() and getAttribute() in servlet? 关于级联,休眠中的 save() 和 persists() 方法有什么区别? - what's the difference between save() and persists() methods in hibernate regarding with cascading? AST:访问和仅使用查询方法有什么区别? - AST: what's the difference between visiting and just using query methods? Java向量方法set()和setElementAt()有什么区别? - What's the difference between the java vector methods set() and setElementAt()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM