URL'yi tamamlamak için HttpServletRequest


Yanıtlar:


393

HttpServletRequestAşağıdaki yöntemleri vardır:

  • getRequestURL() - tam URL'nin sorgu dizesi ayırıcı karakterinden önceki kısmını döndürür ?
  • getQueryString() - tam URL'nin sorgu dizesi ayırıcı karakterinden sonraki kısmını döndürür ?

Tam URL'yi almak için şunları yapmanız yeterlidir:

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
Açıklamayı getRequestURI'den (yanlış) kopyaladınız ancak kodda getRequestURL kullanın (sağda).
Vinko Vrsalovic

21
Sorgu dizesinin boş olup olmadığını koşullu olarak kontrol etmeniz gerekir.
Adam Gent

8
Ayrıca istek URL'sini yedekleyen StringBuffer'ı değiştiriyorsunuz. İstek uygulaması savunma amaçlı bir kopya oluşturmuyorsa, kodun diğer formlarında orijinal biçiminde bekleyen garip davranışları ve hataları tanıtmanın çok iyi bir yoludur.
Ken Blair

5
StringBuffer yerine StringBuilder kullanın
Gladwin Burboz

17
@KenBlair: Bir StringBuffer bilerek iade edilir, böylece daha fazla saklamaya kolayca ekleyebilirsiniz. Bu javadoc üzerinde belirtildiğinden, döndürülen StringBuffer'ın arayan tarafından değiştirilmemesini beklemek uygulamanın son derece saçma olacağı için bu harika.
stolsvik

145

Bu yöntemi kullanıyorum:

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
Bu, HttpServletRequest'te bulunan tüm bilgi bitlerine hızlı bir başvuru için yararlı bir cevaptır. Ancak, port parçasını sonuca ekleyip eklemeyeceğinize karar verme düzenini kontrol etmek istediğinizi düşünüyorum. Örneğin "https" 443 olur.
Peter Cardona

2
küçük bir optimizasyon sadece bir ipucu, StringBuffer yerine bir StringBuilder kullanmak olacaktır
Chris

11
Sadece bir yorum: iş parçacığı güvenliği, bu özel örnekte bir sorun urldeğildir;
Diogo Kollross

1
Belirtildiği gibi, iş parçacığı güvenliği burada bir sorun değildir, çünkü StringBufferher çağrı için bir örnek oluşturursunuz ve bunu başka bir iş parçacığıyla paylaşmazsınız. Bu, a olarak değiştirilmelidir StringBuilder.
Gri

1
Kullanmamak için bir sebep var getRequestURImı?
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
Avantajını görmezden geliyorsunuz StringBuffer.
BalusC

Evet. Kabul ediyorum, ama sanırım sadece iki ek nesne.
Teja Kantamneni

9
Bu bir ek nesne (StringBuilder) ve döndürülen temel StringBuffer'ı değiştirmez. Aslında bunu "kabul" cevabına tercih ederim, JVM farkı ne olursa olsun optimize eder ve bu hata getirme riski yoktur.
Ken Blair

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

12

Bir Bahar projesinde şunları kullanabilirsiniz:

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

3
Neden olmasın? new ServletServerHttpRequest(request).getURI()
Matt Sidesinger

URI URL değil
Sllouyssgort

6

HttpU kullanımdan kaldırılana kadar bu doğru yöntemdir

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


1

Filtre kullanabilirsiniz.

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





    }

web.xml'de <dispatcher>FORWARD</dispatcher>filtre eşlemeyi koymayı unutmayın


kayıt için ... test1.getRequestURI ()); /applicationName/menu/index.action (yani baştaki eğik çizgiyi içerir) verir
Stevko

1

HttpServletRequest nesnesinde aşağıdaki yöntemleri kullanın

java.lang.String getRequestURI () -Bu isteğin URL'sinin, protokol adından HTTP isteğinin ilk satırındaki sorgu dizesine kadar olan kısmını döndürür.

java.lang.StringBuffer getRequestURL () -İstemcinin istekte bulunmak için kullandığı URL'yi yeniden oluşturur.

java.lang.String getQueryString () -Yoldan sonra istek URL'sinde bulunan sorgu dizesini döndürür.


0

Biraz geç partiye, ama benim bu dahil MarkUtils-Web kütüphanede yer WebUtils - Checkstyle onaylı ve JUnit test edilmiş:

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

Muhtemelen burada şimdiye kadar Mat Banik'in arkasındaki en hızlı ve en sağlam cevap - ama onun bile HTTP / HTTPS ile standart dışı potansiyel port yapılandırmalarını hesaba katmıyor.

Ayrıca bakınız:


0

Üçlü bir basit bir astar yazabilirsiniz ve eğer StringBuffer'ın oluşturucu desenini kullanırsanız .getRequestURL():

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

Ama bu sadece sözdizimsel şeker.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.