HttpServletRequest zum Vervollständigen der URL


247

Ich habe ein HttpServletRequestObjekt.

Wie erhalte ich die vollständige und genaue URL, die dazu geführt hat, dass dieser Anruf bei meinem Servlet eingegangen ist?

Oder zumindest so genau wie möglich, da es vielleicht Dinge gibt, die regeneriert werden können (vielleicht die Reihenfolge der Parameter).



warum wir keine util-Funktion dafür hatten
vanduc1102

Antworten:


392

Das HttpServletRequesthat die folgenden Methoden:

  • getRequestURL() - gibt den Teil der vollständigen URL vor dem Trennzeichen für die Abfragezeichenfolge zurück ?
  • getQueryString() - Gibt den Teil der vollständigen URL nach dem Trennzeichen für die Abfragezeichenfolge zurück ?

Um die vollständige URL zu erhalten, gehen Sie einfach wie folgt vor:

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
Sie haben die Beschreibung von getRequestURI kopiert (falsch), aber getRequestURL im Code verwendet (richtig).
Vinko Vrsalovic

21
Sie müssen bedingt prüfen, ob die Abfragezeichenfolge leer ist.
Adam Gent

8
Sie mutieren auch den StringBuffer, der die Anforderungs-URL unterstützt. Wenn die Anforderungsimplementierung keine defensive Kopie erstellt, ist dies eine sehr gute Möglichkeit, seltsames Verhalten und Fehler in andere Teile des Codes einzuführen, die dies in seiner ursprünglichen Form erwarten.
Ken Blair

5
Verwenden Sie StringBuilder anstelle von StringBuffer
Gladwin Burboz

17
@ KenBlair: Ein StringBuffer wird absichtlich zurückgegeben, damit Sie problemlos mehr Stash hinzufügen können. Da dies im Javadoc angegeben ist, wäre es für die Implementierung äußerst absurd zu erwarten, dass der zurückgegebene StringBuffer vom Aufrufer nicht geändert wird - daher ist dies cool.
Stolsvik

145

Ich benutze diese Methode:

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
Dies ist eine hilfreiche Antwort für eine Kurzreferenz zu allen auf HttpServletRequest verfügbaren Informationen. Ich denke jedoch, dass Sie das Schema überprüfen möchten, um zu entscheiden, ob das Portstück zum Ergebnis hinzugefügt werden soll. "https" wäre zum Beispiel 443.
Peter Cardona

2
Eine kleine Optimierung wäre, einen StringBuilder anstelle von StringBuffer zu verwenden, nur ein Hinweis
Chris

11
Nur ein Kommentar: Die Thread-Sicherheit ist in diesem speziellen Beispiel kein Problem, da urlsie nur innerhalb der Methode deklariert, instanziiert und verwendet wird, sodass von anderen Threads als dem, auf den die Methode aufgerufen wurde, nicht zugegriffen werden kann.
Diogo Kollross

1
Wie bereits erwähnt, ist die Thread-Sicherheit hier kein Problem, da Sie StringBufferfür jeden Aufruf eine Instanz von erstellen und diese nicht für andere Threads freigeben. Dies sollte geändert werden, um a zu sein StringBuilder.
Grau

1
Gibt es einen Grund, nicht zu verwenden 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
Sie ignorieren den Vorteil von StringBuffer.
BalusC

Ja. Ich akzeptiere es, aber es sind nur zwei zusätzliche Objekte, denke ich.
Teja Kantamneni

9
Es ist ein zusätzliches Objekt (ein StringBuilder) und mutiert nicht den zugrunde liegenden StringBuffer, der zurückgegeben wird. Ich würde dies der "akzeptierten" Antwort vorziehen, die JVM wird den Unterschied unabhängig davon optimieren und dies birgt nicht das Risiko, Fehler einzuführen.
Ken Blair

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

12

In einem Spring-Projekt können Sie verwenden

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

3
Warum nicht? new ServletServerHttpRequest(request).getURI()
Matt Sidesinger

URI ist es nicht URL
Sllouyssgort

6

Wenn HttpUtil veraltet ist, ist dies die richtige Methode

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


1

Sie können Filter verwenden.

@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);





    }

Vergessen Sie nicht, die <dispatcher>FORWARD</dispatcher>Filterzuordnung in web.xml einzufügen


für die Aufzeichnung ... test1.getRequestURI ()); es gibt /applicationName/menu/index.action (dh es enthält den führenden Schrägstrich)
Stevko

1

Verwenden Sie die folgenden Methoden für das HttpServletRequest-Objekt

java.lang.String getRequestURI () - Gibt den Teil der URL dieser Anforderung vom Protokollnamen bis zur Abfragezeichenfolge in der ersten Zeile der HTTP-Anforderung zurück.

java.lang.StringBuffer getRequestURL () - Rekonstruiert die URL, über die der Client die Anforderung gestellt hat.

java.lang.String getQueryString () - Gibt die Abfragezeichenfolge zurück, die in der Anforderungs-URL nach dem Pfad enthalten ist.


0

Etwas spät zur Party, aber ich habe dies in meine MarkUtils- Webbibliothek in WebUtils aufgenommen - Checkstyle-genehmigt und JUnit-getestet:

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;
    }
}

Wahrscheinlich die schnellste und robusteste Antwort hier hinter Mat Baniks - aber selbst seine berücksichtigt mögliche nicht standardmäßige Portkonfigurationen mit HTTP / HTTPS nicht.

Siehe auch:


0

Sie können einen einfachen Einzeiler mit einem Ternär schreiben und wenn Sie das Builder-Muster des StringBuffers verwenden, aus .getRequestURL():

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

Aber das ist nur syntaktischer Zucker.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.