Solución:
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 bajo /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 localhost:8480
y el nombre 30thh.loc
se puso en el sistema operativo hosts
expediente.
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 él.
-
Si el
url-pattern
en el mapeo de servlet no termina con*
(por ejemplo/test
o*.jsp
),getPathInfo()
devolucionesnull
.
Si se usa Spring MVC
-
Método
getPathInfo()
devolucionesnull
. -
Método
getServletPath()
devuelve la parte entre la ruta de contexto y el ID de sesión. En el ejemplo anterior, el valor sería/test?/a?+b
-
Tenga cuidado con las partes codificadas en URL de
@RequestMapping
y@RequestParam
en primavera. Tiene errores (versión actual 3.2.4) y normalmente 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 como getRequestURI()
da el URI completo.
Hubiera pensado que serían diferentes, dado que un Servlet debe configurarse con su propio patrón URI en primer lugar; No creo que haya servido nunca un Servlet desde root (/).
Por ejemplo, si el Servlet ‘Foo’ se asigna a URI ‘/ foo’, entonces habría pensado que el URI:
/foo/path/to/resource
Resultaría en:
RequestURI = /foo/path/to/resource
y
PathInfo = /path/to/resource
Analicemos la URL completa que un cliente escribiría en su barra de direcciones para llegar a su servlet:
http://www.example.com:80/awesome-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 del 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.
(por cierto, aunque no esté pidiendo esto, el método getRequestURL le daría las partes 1, 2, 3, 4, 5 y 6).
Ahora:
- la parte 4 (la ruta de contexto) se usa para seleccionar su aplicación particular entre muchas otras aplicaciones que pueden estar ejecutándose en el servidor
- la parte 5 (la ruta del servlet) se usa para seleccionar un servlet particular entre muchos otros servlets que pueden estar incluidos en el WAR de su aplicación
- la parte 6 (la información de la ruta) 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 es válido (excepto por las diferencias de codificación de URL):
requestURI = contextPath + servletPath + pathInfo
El siguiente ejemplo de la especificación Servlet 3.0 es muy útil:
Nota: sigue la imagen, no tengo tiempo para recrear en HTML: