从虚拟主机的URL中删除Tomcat上下文(mod_jk,mod_rewrite)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从虚拟主机的URL中删除Tomcat上下文(mod_jk,mod_rewrite)相关的知识,希望对你有一定的参考价值。

我有一个包含许多webapp的Tomcat实例,每个都可以通过它的/ Context访问。 Tomcat是httpd(实际上是Debian Apache2)的后面,配置了虚拟主机来为每个app / Context提供服务。 Tomcat连接与mod_jk连接。

当我不关心从URL中删除上下文时,这很好用:当请求虚拟域的根时,请求被重定向到domain.com/Context。

但是对于一个应用程序,我确实想要删除上下文。我相信这可以通过使用mod_rewrite,并将重写的url传递给mod_jk以传递给正确的Tomcat上下文来完成。所以我的Debian Apache2站点可用文件如下所示:

NameVirtualHost *

<VirtualHost *>
    ServerName domain.be

    DocumentRoot /home/webapp/app/static/domain/

    RewriteEngine on
    RewriteRule ^/(.*)$ /Context/$1 [L,PT]
    RewriteLog "/var/log/apache2/domain-rewrite.log"
    RewriteLogLevel 4

    JkLogFile     /var/log/apache2/domain-mod_jk.log
    JkLogLevel    debug
    JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
    JkMount /Context w1
    JKMount /Context* w1
    JkOptions +ForwardURICompat

    ErrorLog /var/log/apache2/domain_error.log
    CustomLog /var/log/apache2/domain_access.log combined
    LogLevel warn

</VirtualHost>

根据文档,[PT]标志和+ ForwardURICompat选项应该导致重写的URL传递给jk_mod。然而,这似乎并没有发生。

正在重写URL,但似乎mod_jk忽略了它:例如,对domain.be/Context的请求被重写为/ Context / Context - 但仍然作为/ Context传递给mod_jk。

有任何想法吗?顺便说一下,我现在不能使用mod_proxy。

谢谢

答案

@Josh,我认为如果tomcat执行任何重定向,这个解决方案将无效。这是典型情况,例如在要求登录的应用程序中。当用户未经过身份验证时,应用程序将重定向到类似/ login的内容,但是tomcat将在/ context / login中附加当前上下文,以便在上下文中显示在URL中。

正如您在其他问题/响应中提到的那样仅使用mod-jk和tomcat虚拟主机是一个选项,但您需要将应用程序部署为ROOT.war,这可能不是那么简单。有一个解决方法,所以你的应用程序可以放入tomcat webapps文件夹,但正如我所描述的here服务器将至少部署应用程序两次。

如果RewriteRule [P]加上JkOptions + ForwardURICompat可以工作但它没有效果会很棒。顺便说一句,我已经测试了这个,我知道mod_proxy确实有效,因为我将我的网站代理到cnn.com,我的网站在我的网站URL下面。以下是您可以看到正在使用代理的请求的BTW日志:

127.0.0.1 - - [15/Dec/2011:12:56:34 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/
127.0.0.1 - - [15/Dec/2011:12:56:34 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/ [OK]
127.0.0.1 - - [15/Dec/2011:12:56:49 --0500] [localhost/sid#1008ef278][rid#1009aaca8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/login
127.0.0.1 - - [15/Dec/2011:12:56:49 --0500] [localhost/sid#1008ef278][rid#1009aaca8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/login [OK]
127.0.0.1 - - [15/Dec/2011:12:57:15 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/j_spring_security_check
127.0.0.1 - - [15/Dec/2011:12:57:15 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/j_spring_security_check [OK]
127.0.0.1 - - [15/Dec/2011:13:08:41 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/
127.0.0.1 - - [15/Dec/2011:13:08:41 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/ [OK]
另一答案

我一直在使用它取得了巨大的成功:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(Context/.*)$
RewriteRule ^/(.*)$ /Context/$1 [P,L]

您的情况说明:

  • 您将需要使mod_proxy正常工作或[P]将被忽略,并且请求将被转发而不是代理。没有办法解决这个问题。
  • +ForwardURICompat是mod_jk的一部分,将在重写后生效。
  • mod_jk忽略了请求,因为它永远不会到达那里。你需要一个RewriteCond(上面)来防止对/ Context的请求被重写。

我目前正在寻找一种方法来做到这一点,没有mod_rewrite,而是使用just mod_jk and Tomcat <Host>'s。但是我遇到了apache,mod_jk和Tomcat主机在一起玩得很好的问题。以上应该适合你。

另一答案

我会留下原来的答案,但这是错的。正确的方法是使用Tomcat VirtualHost:

http://tomcat.apache.org/tomcat-6.0-doc/virtual-hosting-howto.html

上面链接中的官方演练正是我现在多次使用过的。我不会试图把它煮到这里。

该概念与Apache Vhost相同。创建一个虚拟主机(例如,用于something.yourtdomain.com)并将您的webapp部署到该虚拟主机的ROOT应用程序(/),并且您已完成所有设置。这样,如果您已经有一个ROOT webapp,您可以在另一个域中拥有另一个,并且之前将保持不受影响。

正如Nestor所提到的,Apache重写规则将不会处理诸如标记库和框架之类的内容,这些内容会根据上下文根自动为您创建链接/表单操作/等。在这种情况下,他们将创建正确的上下文根(/)。

另一答案

根据Nestor Urquiza的回答给出的提示,我设法通过在tomcat的server.xml中定义其他主机来解决问题,因为如上所述,tomcat通过向浏览器发出前向指令来回答j_security_check请求,该指令不可避免地包含上下文名称,以便用户尝试登录会收到408错误。因此,Apache VirtualHost JkMount /* worker1指令中的真正直通是通过制作预期的上下文,ROOT指令来实现的。

Apache httpd.conf [和/或包含的* .conf]文件:

<!-- the subdomain -->

<VirtualHost *:80>
    ServerName appWelcome.example.org
    ServerAlias www.appWelcome.example.org
    JKMount /* worker1
</VirtualHost>

<!-- with mod_jk set up -->

LoadModule    jk_module modules/mod_jk.so
JWorkersFile  /etc/apache2/workers.properties
JkShmFile     /var/log/apache2/mod_jk.shm

因此,要将对子域http://appWelcome.example.org/的所有请求直接映射到主管/ appWelcome tomcat上下文,appWelcome上下文必须可以通过请求http://appWelcome.example.org:8080/来寻址

因此,tomcat server.xml文件将为您要提供的应用程序单独使用Host :.

<Server ...>
  <Service>
    <Engine defaultHost="localhost" ...>

      <Host name="appWelcome.example.org" appBase="appWelcomeBase" ... >
        <Valve ... />
      </Host>

      <Host name="localhost" appBase="webapps" ...>
        <!-- this Host is typically shipped with manager, host-manager, docs, 
          sample, examples and a default ROOT context that shows tomcat default home. -->
        <Valve ... />
      </Host>

    </Engine>
  </Service>
</Server>

请注意,必须调整权限(和selinux上下文,如果已启用)以模仿默认的Host,如下所示:

$CATALINA_HOME/conf/Catalina/app.example.org$CATALINA_HOME/conf/Catalina/localhost

$CATALINA_HOME/appWelcomeBase$CATALINA_HOME/webapps

完成这一切后,剩下要做的就是重命名并移动appWelcome.war web存档,以便在创建的appBase中自动部署(用其值替换$ CATALINA_HOME,例如/ var / www / tomcat7):

# mv $CATALINA_HOME/webapps/appWelcome.war $CATALINA_HOME/appWelcomeBase/ROOT.war

瞧!

另一答案

使用mod_proxy_ajp代替mod_jk,如下所示:

<VirtualHost *:80>
  ServerName domain.be

  DocumentRoot /home/webapp/app/static/domain/

  ...

  ProxyPass /Context ajp://localhost:8009/Context
  ProxyPass / ajp://localhost:8009/Context/

  ...
</VirtualHost>

以上是关于从虚拟主机的URL中删除Tomcat上下文(mod_jk,mod_rewrite)的主要内容,如果未能解决你的问题,请参考以下文章

从 URL 中删除上下文名称 - 使用 Spring Security 的 mod_proxy_ajp

如何在 NGINX 的代理响应中重写 URL

mod_rewrite:从 URL 中删除查询字符串?

使用 mod_rewrite 从 url 中删除页面 id

windows下apache代理转发tomcat

从 URL 中删除目录