HttpServletRequest pour compléter l'URL


247

J'ai un HttpServletRequestobjet.

Comment puis-je obtenir l'URL complète et exacte à l'origine de cet appel sur ma servlet?

Ou au moins aussi précisément que possible, car il y a peut-être des choses qui peuvent être régénérées (l'ordre des paramètres, peut-être).



pourquoi nous n'avons pas utilisé de fonction util pour cela
vanduc1102

Réponses:


392

A HttpServletRequestles méthodes suivantes:

  • getRequestURL() - renvoie la partie de l'URL complète avant le caractère séparateur de chaîne de requête ?
  • getQueryString() - renvoie la partie de l'URL complète après le caractère séparateur de chaîne de requête ?

Donc, pour obtenir l'URL complète, faites simplement:

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
Vous avez copié la description de getRequestURI (incorrect) mais utilisez getRequestURL dans le code (à droite).
Vinko Vrsalovic

21
Vous devez vérifier conditionnellement si la chaîne de requête est vide.
Adam Gent du

8
Vous mutez également le StringBuffer soutenant l'URL de demande. Si l'implémentation de la demande ne fait pas de copie défensive, c'est un très bon moyen d'introduire un comportement étrange et des bogues dans d'autres parties du code qui l'attendent sous sa forme originale.
Ken Blair

5
Utilisez StringBuilder au lieu de StringBuffer
Gladwin Burboz

17
@KenBlair: Un StringBuffer est retourné exprès, de sorte que vous pouvez facilement ajouter plus de cachette. Comme cela est spécifié sur le javadoc, il serait extrêmement absurde de l'implémentation de s'attendre à ce que le StringBuffer retourné ne soit pas modifié par l'appelant - par conséquent, c'est cool.
stolsvik

145

J'utilise cette méthode:

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
Ceci est une réponse utile pour une référence rapide à tous les bits d'informations disponibles sur HttpServletRequest. Cependant, je pense que vous voudriez vérifier le schéma pour décider d'ajouter ou non la pièce de port au résultat. "https" serait par exemple 443.
Peter Cardona

2
une petite optimisation serait d'utiliser un StringBuilder au lieu de StringBuffer, juste un indice
Chris

11
Juste un commentaire: la sécurité des threads n'est pas un problème dans cet exemple spécifique car elle urlest déclarée, instanciée et utilisée uniquement à l'intérieur de la méthode, donc elle n'est pas accessible à partir de threads autres que celui qui a appelé la méthode.
Diogo Kollross

1
Comme mentionné, la sécurité des threads n'est pas un problème ici car vous créez une instance de votre StringBufferpour chaque appel et ne la partagez pas avec d'autres threads. Cela devrait être changé pour être un StringBuilder.
Gray

1
Une raison de ne pas l'utiliser 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
Vous ignorez l'avantage de StringBuffer.
BalusC

Oui. Je l'accepte, mais ce ne sont que deux objets supplémentaires, je suppose.
Teja Kantamneni

9
C'est un objet supplémentaire (un StringBuilder) et ne mute pas le StringBuffer sous-jacent qui est retourné. Je préférerais en fait cela à la réponse "acceptée", la JVM optimisera la différence indépendamment et cela n'a aucun risque d'introduire des bogues.
Ken Blair

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

12

Dans un projet Spring, vous pouvez utiliser

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

3
Pourquoi pas? new ServletServerHttpRequest(request).getURI()
Matt Sidesinger

URI ce n'est pas une URL
Sllouyssgort

6

HttpUtil étant obsolète, c'est la bonne méthode

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


1

Vous pouvez utiliser un filtre.

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





    }

n'oubliez pas de mettre le <dispatcher>FORWARD</dispatcher>mappage de filtre dans web.xml


pour l'enregistrement ... test1.getRequestURI ()); il donne /applicationName/menu/index.action (c'est-à-dire qu'il contient la barre oblique principale)
Stevko

1

Utilisez les méthodes suivantes sur l'objet HttpServletRequest

java.lang.String getRequestURI () -Retourne la partie de l'URL de cette demande du nom du protocole jusqu'à la chaîne de requête dans la première ligne de la demande HTTP.

java.lang.StringBuffer getRequestURL () -Reconstruit l'URL utilisée par le client pour effectuer la demande.

java.lang.String getQueryString () -Retourne la chaîne de requête contenue dans l'URL de demande après le chemin.


0

Un peu tard pour la fête, mais je l'ai inclus dans ma bibliothèque MarkUtils-Web dans WebUtils - approuvé par Checkstyle et testé par 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;
    }
}

Probablement la réponse la plus rapide et la plus robuste jusqu'ici derrière Mat Banik - mais même la sienne ne tient pas compte des configurations de port non standard potentielles avec HTTP / HTTPS.

Voir également:


0

Vous pouvez écrire un simple liner avec un ternaire et si vous utilisez le modèle de générateur du StringBuffer à partir de .getRequestURL():

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

Mais ce n'est que du sucre syntaxique.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.