[英]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: 部分是:
http
方案: http
www.example.com
主机名: www.example.com
80
港口: 80
awesome-application
上下文路径: awesome-application
path/to/servlet
servlet路径: path/to/servlet
path/info
路径信息: path/info
a=1&b=2
查询: a=1&b=2
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: 现在:
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.