URL을 완성하기위한 HttpServletRequest


247

나는이 HttpServletRequest개체를.

이 호출이 내 서블릿에 도착하게하는 완전하고 정확한 URL을 어떻게 얻습니까?

또는 재생성 할 수있는 것 (매개 변수의 순서)이있을 수 있으므로 가능한 한 정확하게 작성하십시오.



util 함수를 사용하지 않은 이유
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을 사용합니다 (오른쪽).
Vinko Vrsalovic

21
쿼리 문자열이 비어 있는지 조건부로 확인해야합니다.
Adam Gent

8
또한 요청 URL을 지원하는 StringBuffer를 변경하고 있습니다. 요청 구현이 방어 적 복사본을 만들지 않는 경우 원래 형식으로 예상되는 다른 코드 부분에서 이상한 동작과 버그를 발생시키는 매우 좋은 방법입니다.
Ken Blair

5
StringBuffer 대신 StringBuilder를 사용하십시오
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입니다.
Peter Cardona 2016 년

2
작은 최적화는 StringBuffer 대신 StringBuilder를 사용하는 것입니다. 힌트
Chris

11
단지 주석 : 스레드 안전은이 특정 예제에서 문제가되지 않으므로 url메소드 내부에서만 선언, 인스턴스화 및 사용되므로 메소드를 호출 한 스레드 이외의 스레드에서는 액세스 할 수 없습니다.
Diogo Kollross 2016 년

1
언급했듯이 스레드 안전성은 StringBuffer각 호출마다 인스턴스를 생성하고 다른 스레드와 공유하지 않기 때문에 문제가되지 않습니다 . 이로 변경되어야합니다 StringBuilder.
회색

1
사용하지 않는 이유는 getRequestURI무엇입니까?
Christophe Roussy 2016

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은 상관없이 차이를 최적화하며 버그를 도입 할 위험이 없습니다.
Ken Blair

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

12

Spring 프로젝트에서 사용할 수 있습니다

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

3
왜 안돼? new ServletServerHttpRequest(request).getURI()
Matt Sidesinger

URI URL이 아님
Sllouyssgort

6

HttpUtil은 더 이상 사용되지 않습니다. 올바른 방법입니다.

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


1

filter를 사용할 수 있습니다.

@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를 제공합니다 (즉, 슬래시를 포함합니다)
Stevko

1

HttpServletRequest 객체에서 다음 메소드를 사용하십시오.

java.lang.String getRequestURI ()- 이 요청의 URL 부분을 프로토콜 이름에서 HTTP 요청의 첫 번째 행에있는 쿼리 문자열까지 리턴합니다.

java.lang.StringBuffer getRequestURL ()- 클라이언트가 요청을하는 데 사용한 URL을 재구성합니다.

java.lang.String getQueryString ()- 경로 뒤의 요청 URL에 포함 된 쿼리 문자열을 리턴합니다.


0

다소 늦게 파티에,하지만 난 내이 포함 MarkUtils - 웹 라이브러리 에서 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;
    }
}

아마도 지금까지 Mat Banik보다 훨씬 빠르고 강력한 답변 일 것입니다. 그러나 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();
}

그러나 그것은 단지 구문 설탕입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.