使用 mod_proxy_ajp 在 Apache 后面正确设置 Tomcat
我一直在修改 Apache + Tomcat,以便我可以通过 apache(干净且清晰的 url 摇滚)为多个 tomcat 应用程序(在不同的机器中)提供服务。我已成功配置 mod_proxy_ajp
& mod_rewrite
到我可以在不同的机器上提供两个 tomcat 应用程序的程度,几乎没有任何问题。
我发现的唯一问题是其中一个应用程序(我在 Struts2 中开发)有很多链接和表单,它们是用
生成的,
和
标记。这些标签生成的 URL 通常如下所示:
/WebApp/path/to/some.action
感谢 ModRewrite 的魔力,这通常不是一个大问题,并且指向此类 URL 的超链接会被快速重写和删除。重定向到 /app/path/to/some.action
(尽管我确实收到了大量 302
响应)。
真正的问题发生在执行 POST 请求时。大家可能都知道,我无法使用 mod_rewrite 重定向 POST
请求...所以最后...我的所有 POST
请求都不起作用,因为 mod_rewrite 重定向到正确的 url,但作为 GET
请求。
我已经阅读了一些关于 mod_proxy_html
的内容以及它如何帮助我重写 Tomcat Web 应用程序返回的 url...但感觉很麻烦。
这是我当前的 apache 配置:
## HACKING BEGINS RIGHT HERE
# cookies
ProxyPassReverseCookiePath /WebApp /app
# this is for CSS, IMGs, JS and redirecting urls with /WebApp*
RewriteRule ^/WebApp(.*)$ /app$1 [R,L]
<Location /app>
ProxyPass ajp://localhost:8009/WebApp
ProxyPassReverse ajp://localhost:8009/WebApp
Order allow,deny
Allow from all
</Location>
# the other app
ProxyPassReverseCookiePath /WebApp2 /other
<Location /other>
ProxyPass ajp://200.9.4.6:8009/WebApp2
ProxyPassReverse ajp://200.9.4.6:8009/WebApp2
Order allow,deny
Allow from all
</Location>
必须有一个解决方案来解决我的 POST 请求问题...有什么想法吗?我可以以某种方式配置一些东西,让 Struts2 输出正确的 url 吗?
感谢您的帮助。
I've been tinkering with Apache + Tomcat so that I can serve multiple tomcat apps (in different machines) through apache (clean & crisp urls rock). I've succesfully configured mod_proxy_ajp
& mod_rewrite
to the point where I can serve two tomcat apps in different machines with almost no troubles.
The only issue I've found is that one of the apps (which I'm developing in Struts2) has a lot of links and forms, which are generated with <s:a />
, <s:url />
and <s:form />
tags. The urls generated by these tags generally are like this:
/WebApp/path/to/some.action
Thanks to the magic of ModRewrite, this is generally not a big issue and hyperlinks poiting to such urls are quickly rewriten & redirected to /app/path/to/some.action
(although I do get tons of 302
responses).
The real problem occurs when performing POST requests. As you all might know, I cannot redirect POST
requests with mod_rewrite... so in the end... all of my POST
requests don't work because mod_rewrite redirects to the correct url but as a GET
request.
I have already read a bit about mod_proxy_html
and how it can help me rewrite the urls returned by the Tomcat web application... but it feels troublesome.
This is my current apache configuration:
## HACKING BEGINS RIGHT HERE
# cookies
ProxyPassReverseCookiePath /WebApp /app
# this is for CSS, IMGs, JS and redirecting urls with /WebApp*
RewriteRule ^/WebApp(.*)$ /app$1 [R,L]
<Location /app>
ProxyPass ajp://localhost:8009/WebApp
ProxyPassReverse ajp://localhost:8009/WebApp
Order allow,deny
Allow from all
</Location>
# the other app
ProxyPassReverseCookiePath /WebApp2 /other
<Location /other>
ProxyPass ajp://200.9.4.6:8009/WebApp2
ProxyPassReverse ajp://200.9.4.6:8009/WebApp2
Order allow,deny
Allow from all
</Location>
There must be a solution to my POST
requests problem... Any ideas? Can I somehow configure something that will allow Struts2 to output correct urls?
Thanks for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可能有几种方法可以解决这个问题。
如果您能够使用 URL 中使用的相同名称将应用程序部署到 Tomcat,那将是最简单的。因此,您的应用程序
app
将是/webapps/app[.war]
而不是/webapps/WebApp
,这将完全避免重写。否则,以下内容应该有效,并且应该位于当前重写规则之前。
[PT]
应该允许 Apache 仍然代理请求(这在使用mod_jk
时有效,不确定我是否使用/测试过它mod_proxy_ajp
):一旦您的 Bean 处理了 POST 请求,您就可以将该请求发送到将被重定向的 URL。最后,POST URL 对用户来说并不重要,因此它不必是一个漂亮的 URL。
下面的编辑:
我在 Apache mod_proxy 上看到,ProxyPassReverse 应该与
[PT]
标志一起使用。我能够复制您遇到的问题,下面的配置对我有用,它使用一个基本的 JSP 页面,其中包含一个发布到另一个 JSP 页面的表单。There may be a couple ways to go about this.
If you are able to deploy your app to Tomcat under the same name that you are using in the URL, that would be the easiest. So your application
app
would be/webapps/app[.war]
instead of/webapps/WebApp
, this would avoid the rewrite altogether.Otherwise, the following should work, and should go before your current rewrite rule. The
[PT]
should allow Apache to still proxy the request (this works when usingmod_jk
, not sure I've used/tested it withmod_proxy_ajp
):Once your bean has processed the POST request, you could then send the request to a URL that would be redirected. In the end, the POST URL doesn't matter to the user, so it doesn't have to be a pretty URL.
Edits Below:
I saw on the Apache mod_proxy, that ProxyPassReverse should work with the
[PT]
flag. And I was able to replicate the issue you're having, and the below config worked for me with a basic JSP page with a form that posted to another JSP page.这是webapp设置的问题;可能有一种方法可以在 httpd 配置中解决它,但是修复原始的不一致与围绕它进行黑客攻击相比会更干净。
还值得一提的是,Struts 试图通过为您提供上下文感知的非相对 URL 来帮助您;如果你只是让路径匹配,你可以依赖它(而不是与之对抗......)。
因此,只需将 Struts webapp 部署到 /app 和 /other,而不是 /WebApp 和 /WebApp2。 (可能有某种原因这是不可能的——比如如果你实际上没有控制那些其他服务器——但听起来这并不适用)。
This is a problem with the webapp setup; there may be a way to work around it in httpd config, but it's cleaner to fix the original inconsistency vs. hacking around it.
Also worth mentioning that Struts is trying to help you by giving you context-aware, non-relative URLs; if you just make the paths match, you can rely on that (instead of fighting it...).
So, just deploy the Struts webapp to /app and /other, instead of /WebApp and /WebApp2. (There might be some reason this isn't possible -- like if you don't actually control those other servers -- but it sounds like that doesn't apply).
我会避免 URL 重写。它只是打开像这样的蠕虫罐头,让你查看 mod_proxy_html 等,这当然只是更多的蠕虫。相反,只需在 Tomcat 中部署您的应用程序,并使用您可以接受的外部可见的真实 URL。
I would avoid URL rewriting. It just opens cans of worms like this, makes you look into mod_proxy_html, etc, which of course are just yet more worms. Instead just deploy your apps in Tomcat with real URLs you can live with as being visible externally.