在Apache 2代理(mod_proxy)后面的Tomcat Web应用程序中发送重定向

Mah*_*ahe 15 java apache redirect tomcat mod-proxy

我在tomcat上有一个Web应用程序 http://localhost:8080/WebApp/

我已经配置了Apache 2(mod_proy),因此localhost可以直接访问Web应用程序,并输出端口和名称:例如 http://localhost

<VirtualHost localhost:80>
    ProxyPreserveHost On
    ProxyPass / http://localhost:8080/WebApp/
    ProxyPassReverse / http://localhost:8080/WebApp/
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

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");
    }
 }
Run Code Online (Sandbox Code Playgroud)

我使用URL http://localhost/login- 我被重定向到http://localhost/WebApp/a.html

如何获得正确的重定向http://localhost/a.html

Mah*_*ahe 14

感谢Stuart和他对这个博客的链接,我找到了一个解决方案: 反向代理Apache背后的Tomcat Web应用程序

解决方案:必须关闭ProxyPreserveHost!

原因:如果打开,代理后端返回的响应头将包含"localhost"或没有端口号(或80)的真实域.所以ProxyPassReverse模式不匹配(因为端口不同,如果使用另一个域名,域名也不匹配).

配置:

<VirtualHost localhost:80>

   ProxyPreserveHost Off
   ProxyPass /  http://localhost:8080/WebApp/
   ProxyPassReverse / http://localhost:8080/WebApp/

</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

但这只能通过http,而不是通过ajp(我不知道为什么).如果您仍想使用ajp,可以使用以下解决方法 - 让Apache在错误重定向后执行另一个重定向:

<VirtualHost localhost:80>

   ProxyPass /WebApp !
   ProxyPass /  ajp://localhost:8009/WebApp/
   ProxyPassReverse / ajp://localhost:8009/WebApp/

   RedirectMatch 301 ^/WebApp/(.*)$ /$1
   RedirectMatch 301 ^/WebApp$ /

</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

ProxyPass /WebApp !需要该指令来排除mod_proxy中进一步处理的路径(因为在重定向指令之前评估代理指令)

然后,RedirectMatch指令将所有/WebApp/...分别/WebApp指向URL的内容重定向到URL,而不是/WebApp在开头.

唯一的缺点是您不能WebApp在Web应用程序中指定任何子文件夹