2009-11-13 39 views
10

Tomcat提供了“虚拟主机”支持构建:可以将引擎/ Web应用程序配置为负责域列表。必须使用特殊的xml指令将这些域放入server.xml/context.xml文件中。Tomcat:以编程方式更改虚拟主机?

=>是否有可能改变Tomcat配置(一般)和Web的应用程序/引擎编程尤其是“虚拟主机”?

例如,如果新用户注册,我必须将他的域添加到“接受的虚拟主机/域”列表中。我目前唯一想到的方法是通过脚本更改xml文件,然后重新启动Tomcat。

有什么方法可以通过编程方式添加它们通过一些Java-Methods添加运行时?

非常感谢! 扬

回答

6

Tomcat提供API来创建新的虚拟主机。为了访问这个所需的包装器对象,你需要实现一个ContainerServlet。您可以创建虚拟主机这样,

Context context = (Context) wrapper.getParent(); 
    Host currentHost = (Host) context.getParent(); 
    Engine engine = (Engine) currentHost.getParent(); 

    StandardHost host = new StandardHost(); 
    host.setAppBase(appBase); 
    host.setName(domainName); 

    engine.addChild(host); 

你需要确保appBase目录存在,你必须想办法坚持新主机到server.xml或者你失去在重新启动主机。

但是,这种方法很少有效。如果您的用户运行自己的应用程序,那么您确实需要运行单独的Tomcat实例,以便更好地对应用程序进行沙盒。例如一个内存不足的应用程序不会杀死所有其他应用程序。

如果您提供的应用程序,您可以使用一个主机(defaultHost)。您可以从Host标题获取域名,并在代码中执行任何特定于域的内容。

+1

你好ZZ编码器,谢谢你的回答。这很有趣,从来没有听说过这个,知道有很多方法可以访问Tomcat中的主机和引擎。 – jan

+0

@Coder,如何获得'wrapper'对象 – Kainix

+0

@Kainix您需要创建一个实现ContainerServlet的Servlet,它具有setter setWrapper()。 Tomcat会调用你的setter来设置包装器。自从Tomcat 5以来我没有使用过这个机制,所以这个机制可能已经改变了。 –

1

我建议你设置你的应用程序是在server.xml中默认的虚拟主机让你单虚拟主机可以响应的请求给任何主机名。 Tomcat随本地主机应用程序设置为默认虚拟主机。所以你可以通过简单地检查一个vanilla tomcat安装的server.xml文件来了解如何做到这一点。您可以通过编程方式确定用户使用ServletRequest.getServerName()方法发送请求的主机名。

Tomcat用于发布名为“主机管理器”的Web应用程序。注意:这与Tomcat附带的“经理”Web应用程序不同。主机管理器允许在不重新启动服务器的情况下即时更改配置或添加新的虚拟主机。您可以通过HTTP与主机管理器进行交互(如果需要,可以通过编程方式)。但是,它有一个不幸的缺陷,就是没有对server.xml进行更改,所以它们在重新启动Web服务器时都丢失了。无论出于何种原因,从版本6开始,Tomcat不再包含主机管理器应用程序。所以它似乎不再受到支持。

+0

亚萨您好,非常感谢您的回答! – jan

3

您不应该以编程方式更改服务器环境,也没有可靠的标准方法来执行此操作。最好的做法是将所有这些都保存在Web应用程序端。首先,Filter非常适合这个。将名称存储在缓存在应用程序作用域中的数据库表或属性文件中。检查HttpServletRequest#getRequestURI()(或getServerName()如果它是子域而不是pathinfo)并相应地执行转发任务。

希望这会有所帮助。

+0

你好BalusC,非常感谢你的回答! – jan

+0

我认为这是做到这一点的最佳方式。为什么需要一个数据库映射?我们能不能简单地将网络应用程序映射到子域? – Sorter

3

使用JMX

ArrayList serverList = MBeanServerFactory.findMBeanServer(null); 
MBeanServer server = (MBeanServer) serverList.get(0); 
Object[] params = { "org.apache.catalina.core.StandardHost", hostName }; 
String[] signature = { "java.lang.String", "java.lang.String" }; 
server.invoke(new ObjectName("Catalina:type=Engine"), "addChild", params, signature); 

如果需要的话,检索主机对象,并使用它:

ObjectName host = new ObjectName("Catalina:type=Host,host=" + hostName); 
server.setAttribute(host, new Attribute("autoDeploy", false)); 
server.invoke(host, "start", null, null); 
+0

感谢您的发布!请勿在您的帖子中使用签名/标语。您的用户箱计为您的签名,您可以使用您的个人资料发布您喜欢的任何关于您自己的信息。 [关于签名/标语的常见问题](http://stackoverflow.com/faq#signatures) –