Tomcat:getHeader(“Host”)与getServerName()

我有一个Tomcat应用程序,它是从多个域提供的。 以前的开发人员构建了一个返回应用程序URL的方法(见下文)。 在该方法中,它们请求服务器名称( request.getServerName() ),该名称适当地从httpd.conf文件返回ServerName

但是,我不希望这样。 我想要的是浏览器发送请求的主机名,即浏览器从哪个域访问应用程序。

我尝试了getHeader("Host") ,但仍然返回httpd.conf文件中设置的ServerName

而不是request.getServerName() ,我应该使用什么来获取浏览器发送请求的服务器名称?

例如:

  • httpd.conf中的 ServerName: www.myserver.net
  • 用户访问www.yourserver.net上的 Tomcat应用程序

我需要返回www.yourserver.net而 不是 www.myserver.netrequest.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(); } 

提前致谢!

您需要确保httpd将客户端提供的Host头传递给Tomcat。 最简单的方法(假设您使用的是mod_proxy_http – 您没有说)具有以下内容:

 ProxyPreserveHost On 

如何使用我在这个演示JSP中所做的事情?

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

也许与这个问题无关。 如果您使用的是tomcat,则可以在请求标头中指定任何主机字符串,甚至是javascript,如

然后它可以显示在页面上:

 

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

所以你需要在使用它之前validation它。

这确实是非常有问题的,因为有时您甚至不知道您希望成为完全限定域的主机在哪里被删除。 @rickz提供了一个很好的解决方案,但这是另一个我认为更完整并涵盖许多不同url的解决方案:

基本上,您删除协议(http://,https://,ftp://,…)然后删除端口(如果存在),然后删除整个URI。 这为您提供了顶级域和子域的完整列表。

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

我使用内联方法定义在scala中执行此操作,但上面的代码更详细,因为我发现在纯java中发布解决方案更好。 因此,如果您为此创建方法,您可以将它们链接起来执行以下操作:

 removeURI(removePort(removeProtocol(requestURL)))