2010-02-08 25 views
183

我有一個HttpServletRequest對象。HttpServletRequest完成URL

如何獲得導致此調用到達我的servlet的完整URL和確切URL?或者至少儘可能準確,因爲有可能重新生成的東西(可能是參數的順序)。

+0

另見:http://stackoverflow.com/questions/4931323/whats-the-difference-between-getrequesturi-and- getpathinfo-methods-in-httpservl – 2015-11-12 15:16:21

+0

爲什麼我們沒有使用util函數 – vanduc1102 2016-06-21 08:19:42

回答

290

HttpServletRequest有以下方法:

  • getRequestURL() - 返回完整的URL的查詢字符串分隔符之前的部分?
  • getQueryString() - 查詢字符串分隔符?後返回完整的URL的一部分

所以,要得到完整的網址,只需要:

public static String getFullURL(HttpServletRequest request) { 
    StringBuffer requestURL = request.getRequestURL(); 
    String queryString = request.getQueryString(); 

    if (queryString == null) { 
     return requestURL.toString(); 
    } else { 
     return requestURL.append('?').append(queryString).toString(); 
    } 
} 
+2

您從getRequestURI複製了描述(錯誤),但是在代碼中使用了getRequestURL(右)。 – 2010-02-08 14:56:01

+0

謝謝,miscopy-pasting :) – Bozho 2010-02-08 15:15:56

+16

您需要有條件地檢查查詢字符串是否爲空。 – 2010-09-15 20:43:07

5

結合getRequestURL()getQueryString()的結果應該會得到您想要的結果。

+0

如何處理帖子相關的參數? – flash 2014-05-29 05:58:35

+2

@flash嚴格來說,POST參數不是URL的一部分,它們是請求的_body_。 – Geert 2014-06-30 12:06:40

6

HttpUtil被棄用,這是正確的方法

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

此課程已棄用。 – Bozho 2010-02-08 14:45:32

26
// 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 2010-02-08 14:45:24

+0

是的。我接受它,但我猜它只有兩個額外的物體。 – 2010-02-08 15:36:05

+9

它是*一個*附加對象(一個StringBuilder),並不會改變返回的底層StringBuffer。我實際上比「接受」的答案更喜歡這個,JVM會優化差異,而且這不會引入錯誤。 – 2012-05-22 16:55:29

115

我用這個方法:

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(); 
} 
+7

這是一個快速參考到HttpServletRequest上可用信息的所有位。不過,我想你會想要在決定是否將端口片添加到結果中時檢查該方案。例如,「https」將是443。 – 2012-06-20 00:52:28

+2

一個小的優化是使用StringBuilder而不是StringBuffer,只是一個提示 – Chris 2013-10-22 15:32:01

+0

這取決於如果你需要同步的事實。我認爲安全比對不起。所以,如果任何人需要更快的代碼,他們應該使用StringBuilder,但如果你想要線程安全的話,堅持這個答案。 – 2013-10-22 19:24:16

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





    } 

DONOT忘記把<dispatcher>FORWARD</dispatcher>在過濾器映射在web.xml中

+0

用於記錄... test1.getRequestURI());它給/applicationName/menu/index.action(即它包含前導斜槓) – Stevko 2015-12-22 23:19:39

0

使用上的HttpServletRequest以下方法對象

java.lang.String中getRequestURI() - 返回該請求的URL從部分協議名稱直到HTTP請求的第一行中的查詢字符串。

java.lang.StringBuffer getRequestURL() - 重建客戶端用來發出請求的URL。

java.lang.String getQueryString() - 返回路徑後請求URL中包含的查詢字符串。

3

在Spring項目,你可以使用

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

爲什麼不呢? 'new ServletServerHttpRequest(request).getURI()' – 2017-03-13 16:26:13

0

有點遲到了,但我包括這在我的MarkUtils-Web libraryWebUtils - 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 Mat Banik的最快速和最健壯的答案 - 但即使他沒有考慮使用HTTP/HTTPS進行潛在的非標準端口配置。

參見: