Java 在 Apache 2 代理 (mod_proxy) 后面的 Tomcat Web 应用程序中发送重定向
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18333252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sending redirect in Tomcat web application behind a Apache 2 proxy (mod_proxy)
提问by Mahe
I have a web application on tomcat http://localhost:8080/WebApp/
我在 tomcat 上有一个 Web 应用程序 http://localhost:8080/WebApp/
The I have configrued Apache 2 (mod_proy) so that the web application is directly accessible by localhost with out port and name: e.g http://localhost
我已经配置了 Apache 2 (mod_proy),以便 localhost 可以直接访问 web 应用程序,无需端口和名称:例如 http://localhost
<VirtualHost localhost:80>
ProxyPreserveHost On
ProxyPass / http://localhost:8080/WebApp/
ProxyPassReverse / http://localhost:8080/WebApp/
</VirtualHost>
The index.html is shown correctly on http://localhost
.
But if a servlet redirects:
index.html 在 上正确显示http://localhost
。但是如果 servlet 重定向:
@WebServlet(description = "...", urlPatterns = { "/login" })
public class LoginServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
response.sendRedirect("a.html");
}
}
and I use the URL http://localhost/login
- I am redirected to http://localhost/WebApp/a.html
我使用 URL http://localhost/login
- 我被重定向到http://localhost/WebApp/a.html
How do I get the correct redirect to http://localhost/a.html
?
如何获得正确的重定向http://localhost/a.html
?
采纳答案by Mahe
Thanks to Stuart and his link to this blog I found a solution: Reverse Proxying Tomcat Web Applications Behind Apache
感谢 Stuart 和他指向此博客的链接,我找到了一个解决方案: 反向代理 Apache 背后的 Tomcat Web 应用程序
Solution: ProxyPreserveHost must be turned off!
解决方案:必须关闭ProxyPreserveHost!
Reason: If it is switched on, the response headers returned by the proxy backend will contain “localhost” or the real domain without the port number (or 80). So the ProxyPassReverse pattern does not match (because of the different port and if another domain name is used, also the domain name will not match).
原因:如果开启,代理后端返回的响应头将包含“localhost”或不带端口号的真实域(或80)。所以ProxyPassReverse模式不匹配(因为不同的端口,如果使用另一个域名,域名也不会匹配)。
Config:
配置:
<VirtualHost localhost:80>
ProxyPreserveHost Off
ProxyPass / http://localhost:8080/WebApp/
ProxyPassReverse / http://localhost:8080/WebApp/
</VirtualHost>
But this works only via http, not via ajp (I don't know why). If you still want to use ajp you could use the following workaround - Let Apache do another redirect after the wrong redirect:
但这只能通过http,而不是通过ajp(我不知道为什么)。如果您仍然想使用 ajp,您可以使用以下解决方法 - 让 Apache 在错误重定向后进行另一个重定向:
<VirtualHost localhost:80>
ProxyPass /WebApp !
ProxyPass / ajp://localhost:8009/WebApp/
ProxyPassReverse / ajp://localhost:8009/WebApp/
RedirectMatch 301 ^/WebApp/(.*)$ /
RedirectMatch 301 ^/WebApp$ /
</VirtualHost>
The ProxyPass /WebApp !
directive is needed to exclude the path from further processing in mod_proxy (because proxy directives are evaluated before redirect directives)
该ProxyPass /WebApp !
指令需要从 mod_proxy 中的进一步处理中排除路径(因为代理指令在重定向指令之前进行评估)
Then the RedirectMatch
directives redirect everything stating with /WebApp/...
respectively /WebApp
to the URL without /WebApp
at the beginning.
然后RedirectMatch
指令将所有内容/WebApp/...
分别重定向/WebApp
到没有/WebApp
开头的 URL 。
The only drawback is that you must not have any sub folder named WebApp
in your web application
唯一的缺点是你不能WebApp
在你的 web 应用程序中命名任何子文件夹
回答by Ramnath
you have use to AJP Connector to connect apache2 & tomcat , it will be the perfect solutions for this.
您已经使用 AJP Connector 连接 apache2 和 tomcat,这将是完美的解决方案。
if you need how to configure this, tell me i will explain this detail
如果你需要如何配置这个,告诉我我会解释这个细节
回答by Usman Mutawakil
Use forwarding instead of redirection
使用转发而不是重定向
I think your problem is the use of sendRedirect. Calling sendRedirect is actually suppose to show the browser that the URL has been redirected. If you want to hide that you need to use forwarding.In your servlet try this instead of sendRedirect.
我认为您的问题是使用 sendRedirect。调用 sendRedirect 实际上是为了向浏览器显示 URL 已被重定向。如果你想隐藏你需要使用转发。在你的 servlet 中试试这个而不是 sendRedirect。
String servletPath = request.getServletPath();
if(servletPath.equals("/app1")){
ServletContext ctx = request.getServletContext().getContext("/app1");
RequestDispatcher dispatcher=ctx.getServletContext().getRequestDispatcher( "/app1/app1.html" ); // or wherever you actually keep app1.html
dispatcher.forward( request, response );
}
Inside your context.xml set crossContext = "true" so you can forward requests to other web applications.
在您的 context.xml 中设置 crossContext = "true" 以便您可以将请求转发到其他 Web 应用程序。
<Context crossContext="true" ....../>
回答by Stuart
I also had this problem and spent some time on it. I believe that if you change your apache httpd configuration to the following your redirect will work:
我也遇到了这个问题,并花了一些时间解决它。我相信,如果您将 apache httpd 配置更改为以下内容,您的重定向将起作用:
<VirtualHost localhost:80>
ProxyPreserveHost On
ProxyPass / http://localhost:8080/WebApp/
ProxyPassReverse / http://localhost/WebApp/
ProxyPassReverseCookiePath /WebApp /
</VirtualHost>
This is because the tomcat response headers will contain the proxy headers (i.e. the Location header is http://localhost/WebApp
rather than http://localhost:8080/WebApp
) because ProxyPreserveHost is switched On.
这是因为 tomcat 响应头将包含代理头(即 Location 头是http://localhost/WebApp
而不是http://localhost:8080/WebApp
),因为 ProxyPreserveHost 被打开。
As a footnote: This also works with you want to change your webapps context. Say you wanted to change the publicly visible context to context you can use the following:
作为脚注:这也适用于您想要更改您的 webapps 上下文。假设您想将公开可见的上下文更改为上下文,您可以使用以下内容:
<VirtualHost localhost:80>
ProxyPreserveHost On
ProxyPass /context/ http://localhost:8080/WebApp/
ProxyPassReverse /context/ http://localhost/WebApp/
ProxyPassReverseCookiePath /WebApp /context
</VirtualHost>
For reference, I found this blog post extremely helpful: Reverse Proxying Tomcat Web Applications Behind Apache
作为参考,我发现这篇博文非常有帮助:反向代理 Apache 背后的 Tomcat Web 应用程序
回答by Manik Maurya
I had the same problem while tried to redirect the apache2(running on port 80) request to tomcat(application server running on port 8080).
我在尝试将 apache2(在端口 80 上运行)请求重定向到 tomcat(在端口 8080 上运行的应用程序服务器)时遇到了同样的问题。
This is the configuration which is working perfectly.
这是完美运行的配置。
Go to /etc/apache2/sites-available/000-default.conf
and add the following config:
转到/etc/apache2/sites-available/000-default.conf
并添加以下配置:
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
# for redirecting the websocket requests
ProxyPass /ws ws://localhost:7681/
#ProxyPass /ws ws://localhost:7681/
ProxyPassReverse /ws ws://localhost:7681/
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
# for redirecting the http request
ProxyPass /applicationContextUrl ' http://localhost:8080/applicationContextUrl
ProxyPassReverse /applicationContextUrl http://localhost:8080/applicationContextUrl
ProxyPassReverseCookiePath /applicationContextUrl /
ProxyPassReverseCookieDomain localhost applicationContextUrl
ProxyRequests off
ProxyTimeout 15
ErrorLog ${APACHE_LOG_DIR}/nirad_error.log
LogLevel debug
CustomLog ${APACHE_LOG_DIR}/nirad_access.log combined
<Proxy *>
AddDefaultCharset off
Order deny,allow
Allow from all
#Require all denied
Require all granted
Require local
</Proxy>
</VirtualHost>
Done. Now goto terminal and hit the following command.
完毕。现在转到终端并点击以下命令。
sudo a2enmod proxy_http
(for http redirection).sudo a2enmod proxy_wstunnel
(for websocket redirection)- and
sudo service apache2 restart
- run your application server on port 8080
sudo a2enmod proxy_http
(用于 http 重定向)。sudo a2enmod proxy_wstunnel
(用于 websocket 重定向)- 和
sudo service apache2 restart
- 在端口 8080 上运行您的应用程序服务器