Qual è la differenza tra i metodi getRequestURI e getPathInfo in HttpServletRequest?


143

Sto realizzando un controller frontale semplice e molto leggero. Devo abbinare i percorsi delle richieste a diversi gestori (azioni) per scegliere quello corretto.

Sul mio computer locale HttpServletRequest.getPathInfo()e HttpServletRequest.getRequestURI()restituisco gli stessi risultati. Ma non sono sicuro di cosa restituiranno nell'ambiente di produzione.

Quindi, qual è la differenza tra questi metodi e cosa dovrei scegliere?


1
Potresti trovare utile anche questa risposta .
BalusC,

@BalusC: grazie, ho già usato alcuni suggerimenti da quella risposta.
Romano

Questo spiega la differenza con un bel diagramma: agiletribe.wordpress.com/2016/02/23/…
AgilePro

Risposte:


77

getPathInfo()fornisce le informazioni sul percorso extra dopo l'URI, utilizzate per accedere al Servlet, dove getRequestURI()fornisce l'URI completo.

Avrei pensato che sarebbero stati diversi, dato che un Servlet deve essere configurato con il proprio pattern URI in primo luogo; Non credo di aver mai servito un Servlet da root (/).

Ad esempio se Servlet 'Foo' è mappato su URI '/ foo', allora avrei pensato che l'URI:

/foo/path/to/resource

Si tradurrebbe in:

RequestURI = /foo/path/to/resource

e

PathInfo = /path/to/resource

20
vale la pena menzionare il comportamento di decodifica. getRequestURI () non decodifica la stringa. Dove getPathInfo () viene decodificato.
Kavindu Dodanduwa,

1
In alcuni casi getRequestURI()mi dà la stringa "/foo/path/to/resource"come previsto, ma getPathInfo()per lo stesso HttpServletRequestoggetto mi dà null. Cosa sta succedendo nel mondo? EDIT: l'utente risponde "30thh" di seguito.
anddero,

460

Metterò una piccola tabella di confronto qui (solo per averlo da qualche parte):

Servlet è mappato come /test%3F/*e l'applicazione è distribuita in /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

Nell'esempio sopra il server è in esecuzione sul localhost:8480e il nome è 30thh.locstato inserito nel hostsfile OS .

Commenti

  • "+" viene gestito come spazio solo nella stringa di query

  • L'ancoraggio "#a" non viene trasferito sul server. Solo il browser può lavorare con esso.

  • Se la url-patternmappatura nel servlet non termina con *(ad esempio /testo *.jsp), getPathInfo()restituisce null.

Se viene utilizzato Spring MVC

  • Il metodo getPathInfo()ritorna null.

  • Il metodo getServletPath()restituisce la parte tra il percorso di contesto e l'ID sessione. Nell'esempio sopra il valore sarebbe/test?/a?+b

  • Fai attenzione alle parti con codifica URL di @RequestMappinge @RequestParamin primavera. È difettoso (versione corrente 3.2.4) e di solito non funziona come previsto .


20
Sto stampando la tua risposta e la metto come un poster nel nostro ufficio. Ecco quanto è utile!
Ibrahim Arief,

2
If the url-pattern in the servlet mapping does not end with * (for example /test or *.jsp), getPathInfo() returns null.brillante.
Boris Treukhov,

1
Credo entrambi getRequestURI()e getRequestURL()dovrei restituire jsessionid non decodificato, in questo caso S%3F+ID. Almeno lo fa su Tomcat / 8.5.6.
Gediminas Rimsa,

30

Analizziamo l'URL completo che un client digiterebbe nella barra degli indirizzi per raggiungere il servlet:

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

Le parti sono:

  1. schema: http
  2. Nome host: www.example.com
  3. porta: 80
  4. percorso di contesto: awesome-application
  5. percorso servlet: path/to/servlet
  6. informazioni sul percorso: path/info
  7. query: a=1&b=2
  8. frammento: boo

L'URI della richiesta (restituito da getRequestURI ) corrisponde alle parti 4, 5 e 6.

(per inciso, anche se non lo stai chiedendo, il metodo getRequestURL ti darebbe le parti 1, 2, 3, 4, 5 e 6).

Adesso:

  • la parte 4 (il percorso di contesto) viene utilizzata per selezionare l'applicazione specifica da molte altre applicazioni che potrebbero essere in esecuzione nel server
  • la parte 5 (il percorso servlet) viene utilizzata per selezionare un servlet particolare da molti altri servlet che possono essere raggruppati nel WAR dell'applicazione
  • la parte 6 (le informazioni sul percorso) è interpretata dalla logica del servlet (ad es. può indicare una risorsa controllata dal servlet).
  • anche la parte 7 (la query) è disponibile per il servlet usando getQueryString
  • la parte 8 (il frammento) non viene nemmeno inviata al server ed è rilevante e nota solo al client

Quanto segue vale sempre (tranne che per le differenze di codifica URL):

requestURI = contextPath + servletPath + pathInfo

Il seguente esempio dalla specifica Servlet 3.0 è molto utile:


Nota: l' immagine segue, non ho il tempo di ricrearla in HTML:

inserisci qui la descrizione dell'immagine


16

Considera la seguente 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>

Ora, quando premo l'URL http://localhost:8084/JSPTemp1/NewServlet/jhi, invocherà NewServletcome è mappato con il modello sopra descritto.

Qui:

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

Abbiamo quelli:

  • getPathInfo()

    restituisce
    una stringa, decodificata dal contenitore Web, specificando le informazioni sul percorso extra che seguono il percorso del servlet ma prima della stringa di query nell'URL della richiesta; o null se l'URL non ha informazioni sul percorso extra

  • getRequestURI()

    restituisce
    una stringa contenente la parte dell'URL dal nome del protocollo fino alla stringa della query

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.