我正在制作一个简单,非常轻便的前控制器。我需要将请求路径匹配到不同的处理程序(操作),以便选择正确的处理程序。
在我的本地计算机上HttpServletRequest.getPathInfo()
并HttpServletRequest.getRequestURI()
返回相同的结果。但是我不确定他们将在生产环境中返回什么。
那么,这些方法有什么区别,我应该选择什么?
我正在制作一个简单,非常轻便的前控制器。我需要将请求路径匹配到不同的处理程序(操作),以便选择正确的处理程序。
在我的本地计算机上HttpServletRequest.getPathInfo()
并HttpServletRequest.getRequestURI()
返回相同的结果。但是我不确定他们将在生产环境中返回什么。
那么,这些方法有什么区别,我应该选择什么?
Answers:
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
getRequestURI()
给我的字符串"/foo/path/to/resource"
作为预期,但getPathInfo()
对同一HttpServletRequest
对象给我null
。到底是怎么回事?编辑:下面由用户“ 30thh”回答。
我将在此处放置一个小的比较表(只是将其放在某处):
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-pattern
servlet映射中的不以结尾*
(例如/test
或*.jsp
),则getPathInfo()
返回null
。
如果使用Spring MVC
方法getPathInfo()
返回null
。
方法getServletPath()
返回上下文路径和会话ID之间的部分。在上面的示例中,该值为/test?/a?+b
小心的URL编码的部分@RequestMapping
和@RequestParam
在春季。它存在错误(当前版本3.2.4),通常无法按预期工作。
If the url-pattern in the servlet mapping does not end with * (for example /test or *.jsp), getPathInfo() returns null.
辉煌。
getRequestURI()
和getRequestURL()
应该返回未解码的jsessionid,在这种情况下S%3F+ID
。至少它在Tomcat / 8.5.6上执行。
让我们分解一下客户端将在其地址栏中键入以到达您的servlet的完整URL:
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
请求URI(由getRequestURI返回)对应于第4、5和6部分。
(顺便说一句,即使您不要求这样做,方法getRequestURL也会为您提供第1、2、3、4、5和6部分)。
现在:
以下内容始终有效(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()
返回
一个字符串,其中包含从协议名称到查询字符串的URL的一部分