HttpServletRequest per completare l'URL


248

Ho un HttpServletRequestoggetto

Come posso ottenere l'URL completo ed esatto che ha causato l'arrivo di questa chiamata al mio servlet?

O almeno nel modo più accurato possibile, poiché ci sono forse cose che possono essere rigenerate (l'ordine dei parametri, forse).



perché non abbiamo una funzione util per questo
vanduc1102

Risposte:


393

L' HttpServletRequestha i seguenti metodi:

  • getRequestURL() - restituisce la parte dell'URL completo prima del carattere separatore della stringa di query ?
  • getQueryString() - restituisce la parte dell'URL completo dopo il carattere di separazione della stringa di query ?

Quindi, per ottenere l'URL completo, basta fare:

public static String getFullURL(HttpServletRequest request) {
    StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString());
    String queryString = request.getQueryString();

    if (queryString == null) {
        return requestURL.toString();
    } else {
        return requestURL.append('?').append(queryString).toString();
    }
}

3
Hai copiato la descrizione da getRequestURI (errato) ma utilizza getRequestURL nel codice (a destra).
Vinko Vrsalovic,

21
È necessario verificare in modo condizionale se la stringa di query è vuota.
Adam Gent,

8
Stai anche mutando StringBuffer che supporta l'URL della richiesta. Se l'implementazione della richiesta non sta eseguendo una copia difensiva, questo è un ottimo modo per introdurre comportamenti strani e bug in altre parti del codice che si aspettano che sia nella sua forma originale.
Ken Blair,

5
Usa StringBuilder invece di StringBuffer
Gladwin Burboz,

17
@KenBlair: un StringBuffer viene restituito di proposito, in modo da poter aggiungere facilmente più stash. Dato che questo è specificato su javadoc, sarebbe estremamente assurdo dall'implementazione aspettarsi che StringBuffer restituito non venisse modificato dal chiamante - quindi, questo è interessante.
stolsvik,

145

Io uso questo metodo:

public static String getURL(HttpServletRequest req) {

    String scheme = req.getScheme();             // http
    String serverName = req.getServerName();     // hostname.com
    int serverPort = req.getServerPort();        // 80
    String contextPath = req.getContextPath();   // /mywebapp
    String servletPath = req.getServletPath();   // /servlet/MyServlet
    String pathInfo = req.getPathInfo();         // /a/b;c=123
    String queryString = req.getQueryString();          // d=789

    // Reconstruct original requesting URL
    StringBuilder url = new StringBuilder();
    url.append(scheme).append("://").append(serverName);

    if (serverPort != 80 && serverPort != 443) {
        url.append(":").append(serverPort);
    }

    url.append(contextPath).append(servletPath);

    if (pathInfo != null) {
        url.append(pathInfo);
    }
    if (queryString != null) {
        url.append("?").append(queryString);
    }
    return url.toString();
}

8
Questa è una risposta utile per un rapido riferimento a tutti i bit di informazioni disponibili su HttpServletRequest. Tuttavia, penso che vorresti controllare lo schema per decidere se aggiungere il pezzo di porta al risultato. "https" sarebbe 443, per esempio.
Peter Cardona,

2
una piccola ottimizzazione sarebbe quella di utilizzare StringBuilder invece di StringBuffer, solo un suggerimento
Chris,

11
Solo un commento: la sicurezza dei thread non è un problema in questo esempio specifico perché urlviene dichiarata, istanziata e utilizzata solo all'interno del metodo, quindi non è possibile accedervi da thread diversi da quello che ha chiamato il metodo.
Diogo Kollross,

1
Come accennato, la sicurezza dei thread non è un problema in quanto stai creando un'istanza StringBufferper ogni chiamata e non condividendola con altri thread. Questo dovrebbe essere cambiato per essere un StringBuilder.
Gray,

1
Qualche motivo per non usare getRequestURI?
Christophe Roussy,

27
// http://hostname.com/mywebapp/servlet/MyServlet/a/b;c=123?d=789

public static String getUrl(HttpServletRequest req) {
    String reqUrl = req.getRequestURL().toString();
    String queryString = req.getQueryString();   // d=789
    if (queryString != null) {
        reqUrl += "?"+queryString;
    }
    return reqUrl;
}

5
Stai ignorando il vantaggio di StringBuffer.
BalusC

Sì. Lo accetto, ma credo che siano solo due oggetti aggiuntivi.
Teja Kantamneni,

9
È un oggetto aggiuntivo (StringBuilder) e non muta lo StringBuffer sottostante che viene restituito. Preferirei davvero questo rispetto alla risposta "accettata", la JVM ottimizzerà la differenza a prescindere e questo non ha alcun rischio di introdurre bug.
Ken Blair,

(request.getRequestURL (). toString () + ((request.getQueryString ()! = null)? ("?" + request.getQueryString ()): ""))
Alex

12

In un progetto Spring puoi usare

UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request)).build().toUriString()

3
Perchè no? new ServletServerHttpRequest(request).getURI()
Matt Sidesinger,

URI non è URL
Sllouyssgort

6

HttpUtil essere deprecato, questo è il metodo corretto

StringBuffer url = req.getRequestURL();
String queryString = req.getQueryString();
if (queryString != null) {
    url.append('?');
    url.append(queryString);
}
String requestURL = url.toString();


1

Puoi usare il filtro.

@Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
            HttpServletRequest test1=    (HttpServletRequest) arg0;

         test1.getRequestURL()); it gives  http://localhost:8081/applicationName/menu/index.action
         test1.getRequestURI()); it gives applicationName/menu/index.action
         String pathname = test1.getServletPath()); it gives //menu/index.action


        if(pathname.equals("//menu/index.action")){ 
            arg2.doFilter(arg0, arg1); // call to urs servlet or frameowrk managed controller method


            // in resposne 
           HttpServletResponse httpResp = (HttpServletResponse) arg1;
           RequestDispatcher rd = arg0.getRequestDispatcher("another.jsp");     
           rd.forward(arg0, arg1);





    }

non dimenticare di inserire la <dispatcher>FORWARD</dispatcher>mappatura dei filtri in web.xml


per la cronaca ... test1.getRequestURI ()); dà /applicationName/menu/index.action (cioè contiene la barra iniziale)
Stevko

1

Utilizzare i seguenti metodi sull'oggetto HttpServletRequest

java.lang.String getRequestURI () -Restituisce la parte dell'URL di questa richiesta dal nome del protocollo fino alla stringa di query nella prima riga della richiesta HTTP.

java.lang.StringBuffer getRequestURL () -Recostruisce l'URL utilizzato dal client per effettuare la richiesta.

java.lang.String getQueryString () -Restituisce la stringa di query contenuta nell'URL della richiesta dopo il percorso.


0

Un po 'tardi alla festa, ma l'ho incluso nella mia libreria MarkUtils-Web in WebUtils - Approvato da Checkstyle e testato da JUnit:

import javax.servlet.http.HttpServletRequest;

public class GetRequestUrl{
    /**
     * <p>A faster replacement for {@link HttpServletRequest#getRequestURL()}
     *  (returns a {@link String} instead of a {@link StringBuffer} - and internally uses a {@link StringBuilder})
     *  that also includes the {@linkplain HttpServletRequest#getQueryString() query string}.</p>
     * <p><a href="https://gist.github.com/ziesemer/700376d8da8c60585438"
     *  >https://gist.github.com/ziesemer/700376d8da8c60585438</a></p>
     * @author Mark A. Ziesemer
     *  <a href="http://www.ziesemer.com.">&lt;www.ziesemer.com&gt;</a>
     */
    public String getRequestUrl(final HttpServletRequest req){
        final String scheme = req.getScheme();
        final int port = req.getServerPort();
        final StringBuilder url = new StringBuilder(256);
        url.append(scheme);
        url.append("://");
        url.append(req.getServerName());
        if(!(("http".equals(scheme) && (port == 0 || port == 80))
                || ("https".equals(scheme) && port == 443))){
            url.append(':');
            url.append(port);
        }
        url.append(req.getRequestURI());
        final String qs = req.getQueryString();
        if(qs != null){
            url.append('?');
            url.append(qs);
        }
        final String result = url.toString();
        return result;
    }
}

Probabilmente la risposta più veloce e più affidabile qui finora dietro a Mat Banik - ma anche la sua non tiene conto delle potenziali configurazioni di porte non standard con HTTP / HTTPS.

Guarda anche:


0

Puoi scrivere una semplice fodera con un ternario e se usi il modello di generatore di StringBuffer da .getRequestURL():

private String getUrlWithQueryParms(final HttpServletRequest request) { 
    return request.getQueryString() == null ? request.getRequestURL().toString() :
        request.getRequestURL().append("?").append(request.getQueryString()).toString();
}

Ma questo è solo zucchero sintattico.

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.