HttpServletRequest para completar la URL


Respuestas:


392

El HttpServletRequesttiene los siguientes métodos:

  • getRequestURL() - devuelve la parte de la URL completa antes del carácter separador de cadena de consulta ?
  • getQueryString() - devuelve la parte de la URL completa después del carácter separador de cadena de consulta ?

Entonces, para obtener la URL completa, solo haga:

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
Copiaste la descripción de getRequestURI (incorrecto) pero usas getRequestURL en el código (correcto).
Vinko Vrsalovic

21
Debe verificar condicionalmente si la cadena de consulta está vacía.
Adam Gent

8
También está mutando el StringBuffer que respalda la URL de solicitud. Si la implementación de la solicitud no está haciendo una copia defensiva, es una muy buena manera de introducir comportamientos extraños y errores en otras partes del código que lo esperan en su forma original.
Ken Blair

55
Use StringBuilder en lugar de StringBuffer
Gladwin Burboz

17
@KenBlair: se devuelve un StringBuffer a propósito, para que pueda agregar fácilmente más alijo. Dado que esto se especifica en el javadoc, sería extremadamente absurdo de la implementación esperar que el llamador no modificara el StringBuffer devuelto; por lo tanto, esto es genial.
stolsvik

145

Yo uso este método:

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
Esta es una respuesta útil para una referencia rápida a todos los bits de información disponibles en HttpServletRequest. Sin embargo, creo que querría verificar el esquema al decidir si agregar la pieza de puerto al resultado. "https" sería 443, por ejemplo.
Peter Cardona

2
una pequeña optimización sería usar un StringBuilder en lugar de StringBuffer, solo una pista
Chris

11
Solo un comentario: la seguridad de subprocesos no es un problema en este ejemplo específico porque urlse declara, crea instancias y se usa solo dentro del método, por lo que no se puede acceder desde subprocesos que no sean el que llamó al método.
Diogo Kollross

1
Como se mencionó, la seguridad de subprocesos no es un problema aquí ya que está creando una instancia de su StringBufferpara cada llamada y no la comparte con ningún otro subproceso. Esto debería cambiarse para ser a StringBuilder.
Gray

1
¿Alguna razón para no usar 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;
}

55
Estás ignorando la ventaja de StringBuffer.
BalusC

Si. Lo acepto, pero supongo que son solo dos objetos adicionales.
Teja Kantamneni

99
Es un objeto adicional (un StringBuilder) y no muta el StringBuffer subyacente que se devuelve. De hecho, preferiría esto sobre la respuesta "aceptada", la JVM optimizará la diferencia independientemente y esto no tiene el riesgo de introducir errores.
Ken Blair

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

12

En un proyecto Spring puedes usar

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

3
Por qué no? new ServletServerHttpRequest(request).getURI()
Matt Sidesinger

URI no es URL
Sllouyssgort

6

HttpUtil está en desuso, este es el método correcto

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


1

Puedes usar 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);





    }

no se olvide de poner <dispatcher>FORWARD</dispatcher>en el mapeo de filtro en web.xml


para el registro ... test1.getRequestURI ()); da /applicationName/menu/index.action (es decir, contiene la barra inclinada)
Stevko

1

Utilice los siguientes métodos en el objeto HttpServletRequest

java.lang.String getRequestURI (): devuelve la parte de la URL de esta solicitud desde el nombre del protocolo hasta la cadena de consulta en la primera línea de la solicitud HTTP.

java.lang.StringBuffer getRequestURL () -Reconstruye la URL que el cliente usó para realizar la solicitud.

java.lang.String getQueryString (): devuelve la cadena de consulta que está contenida en la URL de solicitud después de la ruta.


0

Un poco tarde para la fiesta, pero incluí esto en mi biblioteca web MarkUtils en WebUtils : aprobado por Checkstyle y probado por 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;
    }
}

Probablemente la respuesta más rápida y robusta aquí hasta ahora detrás de la de Mat Banik, pero incluso la suya no tiene en cuenta las posibles configuraciones de puertos no estándar con HTTP / HTTPS.

Ver también:


0

Puede escribir un trazador de líneas simple con un ternario y si utiliza el patrón de construcción del StringBuffer desde .getRequestURL():

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

Pero eso es solo azúcar sintáctico.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.