Come ottenere l'URI della richiesta senza percorso di contesto?


127

Il metodo request.getRequestURI () restituisce l'URI con il percorso del contesto.

Ad esempio, se l'URL di base di una domanda è http://localhost:8080/myapp/(cioè il percorso di contesto è myapp ) e invito request.getRequestURI()per http://localhost:8080/myapp/secure/users, ritornerà /myapp/secure/users.

Esiste un modo per ottenere solo questa parte /secure/users, ovvero l'URI senza percorso di contesto?


Risposte:


158

Se ti trovi all'interno di un servlet di controllo frontale che è mappato su un modello di prefisso, puoi semplicemente usare HttpServletRequest#getPathInfo().

String pathInfo = request.getPathInfo();
// ...

Supponendo che il servlet nel tuo esempio sia mappato /secure, questo restituirà /usersl'informazione di esclusivo interesse all'interno di un tipico servlet del front controller.

Se il servlet è tuttavia mappato su un pattern suffisso (i tuoi esempi di URL tuttavia non indicano che questo sia il caso), o quando sei effettivamente all'interno di un filtro (quando il servlet da invocare non è ancora necessariamente determinato, quindi getPathInfo()potrebbe tornare null), quindi la soluzione migliore è sottostringa l'URI della richiesta in base alla lunghezza del percorso del contesto utilizzando il Stringmetodo usuale :

HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
// ...

C'è un motivo per usarlo al posto di getServletPath()? Sto scrivendo un filtro e ho notato che getPathInfo()ritorna null, ma getServletPath()restituisce il percorso meno il contesto (adatto per il passaggio al dispatcher della richiesta).
Jason C

@ JasonC: come risposta, getPathInfo()restituisce null se il servlet del front controller non è mappato su un modello di prefisso.
BalusC

Si. Volevo dire: c'è un motivo per cui preferisci getPathInfo su getServletPath? Molte delle altre risposte con punteggio alto qui non usano nemmeno getServletPath, che è ciò che mi rende sospettoso e perché mi chiedo. Ho un progetto servlet su cui sto lavorando e sto cercando di perfezionare le mie abilità.
Jason C

1
@ JasonC: il percorso del servlet è soggetto a modifiche quando è installato un framework MVC basato su servlet come JSF o Spring MVC. Rappresenterà quindi il percorso interno del framework MVC (ad esempio /foo.xhtmlinvece di /foo.jsf) e non l'URI della richiesta effettiva (quello che l'utente finale vedrebbe nella barra degli indirizzi del browser). Il percorso del servlet originale è in tal caso tuttavia risolvibile come attributo di richiesta con chiave RequestDispatcher.FORWARD_SERVLET_PATH. In ogni modo, la domanda richiede esplicitamente l'URI della richiesta (come nella barra degli indirizzi del browser), quindi la risposta è basata su questo.
BalusC

74
request.getRequestURI().substring(request.getContextPath().length())

Eccezionale! Questo e 'esattamente quello che stavo cercando.
artigiano

4
+1 Penso che questa sia una risposta migliore di getPathInfo a causa del fatto che getPathInfo può essere nullo e altre stranezze. Il codice Spring di vari getContextPath e lo rimuove dall'URI proprio come hai fatto invece di getPathInfo.
Adam Gent

32

Con Spring puoi fare:

String path = new UrlPathHelper().getPathWithinApplication(request);

1
Ovviamente avrebbe senso mantenere un'istanza di UrlPathHelper, ad esempio come variabile membro di una classe ...
James

Come possiamo ottenere l'effettivo URL di mappatura della richiesta? Si prega di guida qui: stackoverflow.com/questions/60446807/...
Pra_A

14

getPathInfo () a volte restituisce null. Nella documentazione HttpServletRequest

Questo metodo restituisce null se non c'erano informazioni aggiuntive sul percorso.

Ho bisogno di ottenere il percorso del file senza il percorso del contesto in Filter e getPathInfo () mi restituisce null. Quindi utilizzo un altro metodo: httpRequest.getServletPath ()

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    String newPath = parsePathToFile(httpRequest.getServletPath());
    ...

}

8

Se usi request.getPathInfo () all'interno di un Filter, sembra che tu ottenga sempre null (almeno con jetty).

Questo bug + risposta concisa e non valida allude al problema che penso:

https://issues.apache.org/bugzilla/show_bug.cgi?id=28323

Sospetto che sia correlato al fatto che i filtri vengono eseguiti prima che il servlet riceva la richiesta. Potrebbe essere un bug del contenitore o un comportamento previsto che non sono stato in grado di identificare.

Il contextPath è tuttavia disponibile, quindi la soluzione fforws funziona anche nei filtri. Non mi piace doverlo fare a mano, ma l'implementazione è rotta o


5

Un modo per farlo è riposizionare il percorso del contesto del servelet dall'URI della richiesta.

String p = request.getRequestURI();
String cp = getServletContext().getContextPath();

if (p.startsWith(cp)) {
  String.err.println(p.substring(cp.length());
}

Leggi qui .


-1

Potrebbe essere possibile utilizzare il metodo split per eliminare "/ miaapp", ad esempio:

string[] uris=request.getRequestURI().split("/");
string uri="/"+uri[1]+"/"+uris[2];

3
Ciò causerà problemi se distribuisco la mia applicazione come root e il suo URL di base diventa localhost: 8080 . In questo caso request.getRequestURI () restituirà "/ secure / user" e il tuo metodo split causerà problemi qui. Il codice non dovrebbe dipendere dalla distribuzione.
artigiano
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.