2012-05-02 14 views
10

Mam aplikację Tomcat, która jest wyświetlana z wielu domen. Poprzedni programista zbudował metodę zwracania adresu URL aplikacji (patrz poniżej). W metodzie żądają nazwy serwera (request.getServerName()), która odpowiednio zwraca nazwę ServerName z pliku httpd.conf.Tomcat: getHeader ("Host") vs. getServerName()

Jednak nie chcę tego. Potrzebuję nazwy hosta, na który przeglądarka wysłała żądanie, tj. Do domeny, z której przeglądarka uzyskuje dostęp do aplikacji.

Próbowałem getHeader("Host"), ale to nadal jest zwrócenie ServerName ustawić w httpd.conf pliku.

Zamiast numeru request.getServerName(), co powinienem użyć, aby uzyskać nazwę serwera, do którego wysłała przeglądarka?

Na przykład:

  • ServerName w httpd.conf: www.myserver.net
  • Użytkownik uzyskuje dostęp do aplikacji Tomcat na www.yourserver.net

I musisz zwrócić www.yourserver.netNOTwww.myserver.net. request.getServerName() wywołanie tylko wydaje się powrót 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(); 
} 

Dzięki z góry!

+1

Tomcat nie może nawet zobaczyć pliku 'httpd.conf', nie mówiąc już o zwrocie z niego wartości. Tomcat pobiera hosta serwera z żądania. – EJP

Odpowiedz

15

Musisz się upewnić, że httpd przechodzi nagłówek Host dostarczonych przez klienta do serwera Tomcat. Najprostszym sposobem (zakładając, że używasz mod_proxy_http - nie powiedziałeś) to z następujących powodów:

ProxyPreserveHost On 
+0

Dzięki, Mark. To załatwiło sprawę. –

3

Co powiesz na używanie czegoś podobnego do tego, które zrobiłem w tym pliku demonstracyjnym JSP?

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

Rick, to działało świetnie - chociaż skończyło się na tym, że korzystałem z sugestii Marka, ponieważ nie wymagało to zmiany kodu. –

+0

@rickz Jak jedna jednostka testuje coś takiego? Kluczowym problemem jest tworzenie instancji HttpServletRequest do testowania jednostkowego? Wyszukiwarka Google wyświetla sugestie, które mogą kpić z klasy, ale jeśli kpisz z jej metod, tak naprawdę nie testujesz niczego w tym momencie. Natknąłem się również na bibliotekę httpunit, ale to też nie pomaga. – morpheus

+0

@morpheus Nie wiem, jak byś go przetestował. – rickz

-1

To jest rzeczywiście bardzo problematyczne, ponieważ czasami nawet nie wiem, gdzie gospodarz, że można oczekiwać, aby być w pełni kwalifikowana domena została usunięta. @rickz dostarczył świetne rozwiązanie, ale tutaj jest jeszcze jeden, który uważam za bardziej kompletny i obejmuje wiele różnych adresów URL:

Zasadniczo usuwasz protokół (http: //, https: //, ftp: //, ...) to port (jeśli istnieje), a następnie cały URI. Daje to pełną listę domen najwyższego poziomu i subdomen.

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

Zrobiłem to w Scala za pomocą wbudowanych definicji metody, ale przede kod jest bardziej gadatliwy, bo okazało się, że lepiej pisać rozwiązania w czystej Javie.Jeśli więc stworzysz dla tego metody, możesz połączyć je w taki sposób:

removeURI(removePort(removeProtocol(requestURL))) 
1

Może nie być powiązane z tym pytaniem. Jeśli używasz Tomcat, można podać dowolny ciąg hosta w nagłówku żądania, nawet javascript jak <script>alert(document.cookie);</script>

może to być widoczne na stronie .:

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

Więc trzeba zweryfikować to przed użyciem.