HttpServletRequest для заповнення URL-адреси


247

У мене є HttpServletRequestоб’єкт.

Як я можу отримати повну та точну URL-адресу, яка викликала цей дзвінок на мій сервлет?

Або хоча б якомога точніше, оскільки, можливо, є речі, які можна відновити (можливо, порядок параметрів).



чому ми не використали для нього функцію
vanduc1102

Відповіді:


392

HttpServletRequestМає наступні методи:

  • getRequestURL() - повертає частину повної URL-адреси перед символом роздільника рядка запиту ?
  • getQueryString() - повертає частину повної URL-адреси після символу роздільника рядка запиту ?

Отже, щоб отримати повну URL-адресу, просто зробіть:

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
Ви скопіювали опис з getRequestURI (неправильно), але використовуйте getRequestURL у коді (праворуч).
Вінко Врсалович

21
Вам потрібно умовно перевірити, чи рядок запиту порожній.
Адам Гент

8
Ви також мутуєте StringBuffer, створюючи резервну копію URL-адреси запиту. Якщо реалізація запиту не робить захисну копію, це дуже хороший спосіб ввести дивну поведінку та помилки в інших частинах коду, які очікують його в оригінальному вигляді.
Кен Блер

5
Використовуйте StringBuilder замість StringBuffer
Gladwin Burboz

17
@KenBlair: StringBuffer повертається спеціально, так що ви можете легко додавати більше сховищ. Оскільки це вказано на javadoc, було б надзвичайно абсурдно реалізовувати очікувати, що повернутий StringBuffer не буде змінений абонентом - отже, це круто.
stolsvik

145

Я використовую цей метод:

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
Це корисна відповідь для швидкого посилання на всі біти інформації, доступні в HttpServletRequest. Однак, я думаю, ви б хотіли перевірити схему, вирішивши, чи слід додати порт-фрагмент до результату. Наприклад, "https" було б 443.
Пітер Кардона

2
невеликою оптимізацією було б використовувати StringBuilder замість StringBuffer, лише натяк
Кріс

11
Лише коментар: безпека потоку не є проблемою в цьому конкретному прикладі, тому що urlоголошена, створена в екземплярі та використовується лише всередині методу, тому не можна отримати доступ до інших потоків, крім тієї, що викликала метод.
Діого Коллросс

1
Як було сказано, безпека потоків тут не є проблемою, оскільки ви створюєте екземпляр свого StringBufferкожного виклику і не ділите його з будь-якими іншими потоками. Це слід змінити, щоб бути а StringBuilder.
Сірий

1
Будь-яка причина не використовувати getRequestURI?
Крістоф Руссі

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
Ви ігноруєте перевагу StringBuffer.
BalusC

Так. Я приймаю це, але я думаю, лише два його додаткові об'єкти.
Teja Kantamneni

9
Це один додатковий об'єкт (StringBuilder) і не мутує базовий StringBuffer, який повертається. Я б фактично віддав перевагу цьому над "прийнятою" відповіддю, JVM оптимізує різницю в стороні незалежно від цього, і це не має жодного ризику введення помилок.
Кен Блер

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


6

Якщо застарілий HttpUtil, це правильний метод

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


1

Можна використовувати фільтр.

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





    }

не забудьте поставити <dispatcher>FORWARD</dispatcher>фільтровальне відображення в web.xml


для запису ... test1.getRequestURI ()); він дає /applicationName/menu/index.action (тобто він містить провідну косу
рису

1

На об’єкті HttpServletRequest використовуйте наступні методи

java.lang.String getRequestURI () -повертає частину URL-адреси цього запиту від імені протоколу до рядка запиту в першому рядку HTTP-запиту.

java.lang.StringBuffer getRequestURL () -Реконструює URL-адресу, яку клієнт використовував для подання запиту.

java.lang.String getQueryString () -повертає рядок запиту, який міститься в URL-адресі запиту після шляху.


0

Трохи запізнюємось на вечірку, але я включив це до своєї бібліотеки MarkUtils-Web у WebUtils - затвердженій Checkstyle та перевірено 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;
    }
}

Напевно, найшвидший і надійний відповідь тут далеко за Матом Баніком - але навіть він не враховує потенційних нестандартних конфігурацій портів з HTTP / HTTPS.

Дивитися також:


0

Ви можете написати простий один вкладиш з потрійною, і якщо ви використовуєте шаблон для побудови StringBuffer з .getRequestURL():

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

Але це лише синтаксичний цукор.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.