2009-11-13 70 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) –