2012-05-02 29 views
10

我有一個Tomcat應用程序正在從多個域提供服務。以前的開發人員構建了一個返回應用程序URL的方法(請參見下文)。在該方法中,它們請求服務器名稱(request.getServerName()),其適當地從httpd.conf文件返回服務器名稱Tomcat:getHeader(「主機」)與getServerName()

但是,我不想那樣。我想要的是瀏覽器發送請求的主機名,即瀏覽器從哪個域訪問應用程序。

我試過getHeader("Host"),但仍返回原的httpd.conf文件服務器名集。

而不是request.getServerName(),我應該用什麼來獲取瀏覽器發送請求的服務器名稱?

例如:

  • 服務器名在的httpd.confwww.myserver.net
  • 用戶訪問上www.yourserver.net

我的Tomcat應用需要退貨www.yourserver.net不是www.myserver.net。該request.getServerName()通話似乎只返回www.myserver.net

/** 
* Convenience method to get the application's URL based on request 
* variables. 
* 
* @param request the current request 
* @return URL to application 
*/ 
public static String getAppURL(HttpServletRequest request) { 
    StringBuffer url = new StringBuffer(); 
    int port = request.getServerPort(); 
    if (port < 0) { 
     port = 80; // Work around java.net.URL bug 
    } 
    String scheme = request.getScheme(); 
    url.append(scheme); 
    url.append("://"); 
    url.append(request.getServerName()); 
    if (("http".equals(scheme) && (port != 80)) || ("https".equals(scheme) && (port != 443))) { 
     url.append(':'); 
     url.append(port); 
    } 
    url.append(request.getContextPath()); 
    return url.toString(); 
} 

提前感謝!

+1

Tomcat甚至無法看到'httpd.conf'文件,更不用說從它返回一個值。 Tomcat從請求中獲取服務器主機。 – EJP

回答

15

您需要確保httpd經過客戶到Tomcat提供的Host頭。最簡單的方法(假設你使用mod_proxy_http - 你沒有說)是以下幾點:

ProxyPreserveHost On 
+0

謝謝,馬克。這個伎倆。 –

3

如何使用像我在這個演示JSP中做的事情?

<% 
    String requestURL = request.getRequestURL().toString(); 
    String servletPath = request.getServletPath(); 
    String appURL = requestURL.substring(0, requestURL.indexOf(servletPath)); 
%> 
appURL is <%=appURL%> 
+0

裏克,這工作很好 - 雖然我最終使用了馬克的建議,因爲它不需要更改代碼。 –

+0

@rickz一個單元如何測試這樣的東西?關鍵問題是如何爲單元測試創​​建一個HttpServletRequest實例?谷歌搜索提出了嘲笑這個課程的建議,但是如果你嘲笑它的方法,那麼在那個時候你並沒有真正地測試任何東西。我也遇到了httpunit庫,但這也沒有幫助。 – morpheus

+0

@morpheus我不知道你會如何測試它。 – rickz

-1

這確實是非常有問題的,因爲有時你甚至不知道您所期望的主機是一個完全限定的域名已被刪除。 @rickz提供了一個很好的解決方案,但這裏是另一個我認爲更加完整並且涵蓋了許多不同的網址的網站:

基本上,您將協議(http://,https://,ftp://, ...)然後是端口(如果存在),然後是整個URI。這爲您提供了頂級域名和子域名的完整列表。

String requestURL = request.getRequestURL().toString(); 
String withoutProtocol = requestURL.replaceAll("(.*\\/{2})", "") 
String withoutPort = withoutProtocol.replaceAll("(:\\d*)", "") 
String domain = withoutPort.replaceAll("(\\/.*)", "") 

我使用內聯方法定義這樣做的斯卡拉,但上面的代碼是更詳細的,因爲我發現它更好地張貼在純Java的解決方案。因此,如果你爲此創建方法,你可以鏈接他們做這樣的事情:

removeURI(removePort(removeProtocol(requestURL))) 
1

也許這個問題沒有關係。 如果您正在使用Tomcat,您可以指定在請求頭中的任何主機串,甚至和JavaScript像<script>alert(document.cookie);</script>

然後,它可以在網頁上顯示:

<p> host name is : <%= request.getServerName() %> </p> 

所以,你需要驗證它在使用之前。