java - example - ¿Cuál es la diferencia entre los métodos getRequestURI y getPathInfo en HttpServletRequest?
httpservletrequest example (4)
Considere la siguiente conf de servlet:
<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>
Ahora, cuando http://localhost:8084/JSPTemp1/NewServlet/jhi
la URL http://localhost:8084/JSPTemp1/NewServlet/jhi
, invocará NewServlet
ya que está correlacionado con el patrón descrito anteriormente.
Aquí:
getRequestURI() = /JSPTemp1/NewServlet/jhi
getPathInfo() = /jhi
Tenemos aquellos:
getPathInfo()
devoluciones
una Cadena, decodificada por el contenedor web, especificando la información de ruta adicional que viene después de la ruta del servlet pero antes de la cadena de consulta en la URL de solicitud; o nulo si la URL no tiene información de ruta adicionalgetRequestURI()
devoluciones
una Cadena que contiene la parte de la URL desde el nombre del protocolo hasta la cadena de consulta
Estoy haciendo un controlador frontal simple, muy ligero. Necesito hacer coincidir las rutas de solicitud con diferentes manejadores (acciones) para elegir la correcta.
En mi máquina local HttpServletRequest.getPathInfo()
y HttpServletRequest.getRequestURI()
devuelven los mismos resultados. Pero no estoy seguro de qué volverán en el entorno de producción.
Entonces, ¿cuál es la diferencia entre estos métodos y qué debería elegir?
Desglosemos la URL completa que un cliente escribiría en su barra de direcciones para llegar a su servlet:
http://www.example.com:80/apply-application/path/to/servlet/path/info?a=1&b=2#boo
Las partes son:
- esquema:
http
- nombre de host:
www.example.com
- puerto:
80
- ruta de contexto:
awesome-application
- ruta de servlet:
path/to/servlet
- información de ruta:
path/info
- consulta:
a=1&b=2
- fragmento:
boo
El URI de solicitud (devuelto por getRequestURI ) corresponde a las partes 4, 5 y 6.
( getRequestURL paso, aunque no esté pidiendo esto, el método getRequestURL le dará las partes 1, 2, 3, 4, 5 y 6).
Ahora:
- la parte 4 (la ruta del contexto) se usa para seleccionar su aplicación particular de entre muchas otras aplicaciones que se pueden ejecutar en el servidor
- la parte 5 (la ruta del servlet) se usa para seleccionar un servlet particular de muchos otros servlets que pueden incluirse en la GUERRA de su aplicación
- la parte 6 (la información del camino) es interpretada por la lógica de su servlet (por ejemplo, puede apuntar a algún recurso controlado por su servlet).
- la parte 7 (la consulta) también está disponible para su servlet usando getQueryString
- la parte 8 (el fragmento) ni siquiera se envía al servidor y es relevante y conocida solo por el cliente
Lo siguiente siempre se cumple (excepto las diferencias de codificación URL):
requestURI = contextPath + servletPath + pathInfo
El siguiente ejemplo de la especificación Servlet 3.0 es muy útil:
Nota: la imagen sigue, no tengo tiempo para volver a crear en HTML:
Pondré una pequeña tabla de comparación aquí (solo para tenerla en alguna parte):
El servlet se asigna como /test%3F/*
y la aplicación se implementa en /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
En el ejemplo anterior, el servidor se ejecuta en el servidor localhost:8480
y el nombre 30thh.loc
se puso en el archivo de sistema operativo.
Comentarios
"+" se maneja como espacio solo en la cadena de consulta
El ancla "#a" no se transfiere al servidor. Solo el navegador puede trabajar con eso.
Si el
url-pattern
en el mapeo de servlet no termina con*
(por ejemplo/test
o*.jsp
),getPathInfo()
devuelvenull
.
Si se usa Spring MVC
Método
getPathInfo()
devuelvenull
.Método
getServletPath()
devuelve la parte entre la ruta del contexto y la ID de la sesión. En el ejemplo anterior, el valor sería/test?/a?+b
Tenga cuidado con las partes codificadas por URL de
@RequestMapping
y@RequestParam
en Spring. Tiene errores (versión actual 3.2.4) y, por lo general, no funciona como se esperaba .
getPathInfo()
proporciona la información de ruta adicional después del URI, que se utiliza para acceder a su Servlet, donde getRequestURI()
proporciona el URI completo.
Hubiera pensado que serían diferentes, dado que un Servlet debe configurarse con su propio patrón de URI en primer lugar; No creo haber servido un Servlet desde root (/).
Por ejemplo, si Servlet ''Foo'' está mapeado a URI ''/ foo'', entonces habría pensado que el URI:
/foo/path/to/resource
Daría lugar a:
RequestURI = /foo/path/to/resource
y
PathInfo = /path/to/resource