2009-11-13 3 views
10

Tomcat bietet einen integrierten "Virtual Hosting" Support: Eine Engine/Web-Anwendung kann so konfiguriert werden, dass sie für eine Liste von Domains verantwortlich ist. Diese Domains müssen mit einer speziellen XML-Direktive in die Dateien server.xml/context.xml eingefügt werden.Tomcat: Ändern Sie die virtuellen Hosts programmgesteuert?

=> Gibt es eine Möglichkeit, die Tomcat-Konfiguration (im Allgemeinen) und speziell die "virtuellen Hosts" einer Web-Anwendung/Engine programmgesteuert zu ändern?

Zum Beispiel, wenn ein neuer Benutzer sich anmeldet, muss ich seine Domain der Liste der "akzeptierten virtuellen Hosts/Domains" hinzufügen. Der einzige Weg, an den ich derzeit denke, ist, die XML-Dateien über ein Skript zu ändern und dann Tomcat neu zu starten.

Gibt es eine Möglichkeit, sie hinzufügen hinzufügen Laufzeit über einige Java-Methoden programmgesteuert?

Vielen Dank! Jan

Antwort

6

Tomcat stellt APIs zum Erstellen eines neuen virtuellen Hosts bereit. Um Zugriff auf das Wrapper-Objekt zu erhalten, müssen Sie ein ContainerServlet implementieren. Sie können wie diese virtuellen Host erstellen,

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); 

Sie sicher appBase Verzeichnis vornehmen müssen existieren und Sie müssen Wege finden, den neuen Host an die server.xml zu anhalten oder Sie verlieren den Host, auf Neustart.

Dieser Ansatz funktioniert jedoch selten. Wenn Ihre Benutzer ihre eigenen Apps ausführen, sollten Sie separate Instanzen von Tomcat ausführen, damit Sie die Apps besser im Sandkasten platzieren können. z.B. Bei einer App, die nicht mehr genügend Arbeitsspeicher zur Verfügung hat, werden nicht alle anderen Apps gelöscht.

Wenn Sie die App bereitstellen, können Sie nur einen Host (defaultHost) verwenden. Sie können den Domänennamen von Host Header abrufen und domainspezifische Dinge in Ihrem Code tun.

+1

Hallo ZZ Coder, danke für deine Antwort. Das ist sehr interessant, ich habe nie davon gehört, das ist genial zu wissen, dass es Möglichkeiten gibt, auf den Host und die Engine in Tomcat zuzugreifen. – jan

+0

@Coder, wie man 'wrapper' Objekt bekommt – Kainix

+0

@Kainix Sie müssen ein Servlet erstellen, das ContainerServlet implementiert, das einen Setter setWrapper() hat. Tomcat ruft Ihren Setter zum Einstellen des Wrappers auf. Ich habe dies seit Tomcat 5 nicht mehr verwendet, so dass sich der Mechanismus möglicherweise geändert hat. –

1

Ich würde vorschlagen, dass Sie Ihre Anwendung als Standard-virtuelle Host in server.xml sein, um Ihre einzelne virtuelle Host reagiert auf Anfragen zu jedem Host-Namen angesprochen. Tomcat wird mit der Localhost-Anwendung als Standard-Host ausgeliefert. So können Sie sehen, wie Sie dies tun, indem Sie einfach die Datei server.xml einer Vanilla-Tomcat-Installation prüfen. Sie können den Hostnamen, an den der Benutzer die Anforderung gesendet hat, mithilfe der Methode ServletRequest.getServerName() programmatisch ermitteln.

Tomcat wird mit einer Webanwendung namens "host-manager" ausgeliefert. Hinweis: Dies unterscheidet sich von der Web-Anwendung "manager", die immer noch mit Tomcat geliefert wird. Der Host-Manager konnte die Konfiguration ändern oder neue virtuelle Hosts im laufenden Betrieb hinzufügen, ohne den Server neu zu starten. Sie könnten mit dem Host-Manager über HTTP interagieren (programmgesteuert, falls gewünscht). Es hatte jedoch den bedauerlichen Fehler, seine Änderungen nicht auf server.xml zu übertragen, so dass sie beim Neustart des Webservers verloren gingen. Aus welchem ​​Grund auch immer, ab Version 6 wird Tomcat nicht mehr mit der Host-Manager-Anwendung ausgeliefert. Es scheint also nicht mehr unterstützt zu werden.

+0

Hallo Asaph, vielen Dank für Ihre Antwort! – jan

3

Sie sollten die Serverumgebung nicht programmgesteuert ändern, und es gibt keine zuverlässigen und standardmäßigen Möglichkeiten, dies zu tun. Am besten ist es, alles auf der Webapp-Seite zu tun und zu behalten. Zu Beginn ist eine Filter dafür perfekt geeignet. Speichern Sie die Namen irgendwo in einer Datenbanktabelle oder einer Eigenschaftendatei, die Sie im Anwendungsbereich der Anwendung zwischenspeichern. Überprüfen Sie die HttpServletRequest#getRequestURI() (oder die getServerName(), wenn es eine Subdomäne anstelle von pathinfo ist) und die Weiterleitung Aufgabe entsprechend.

Hoffe, das hilft.

+0

Hallo BalusC, vielen Dank für deine Antwort! – jan

+0

Ich denke, das ist der beste Weg, dies zu tun. Warum wird ein DB-Mapping benötigt? Können wir die Web-App nicht einfach der Sub-Domain zuordnen? – Sorter

3

Verwenden 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); 

Falls erforderlich, das Host-Objekt abrufen und mit ihm arbeiten:

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

Danke für deinen Beitrag! Bitte verwenden Sie keine Signaturen/Taglines in Ihren Beiträgen. Ihre Benutzerbox gilt als Ihre Unterschrift, und Sie können Ihr Profil verwenden, um Informationen über sich selbst zu veröffentlichen. [FAQ zu Unterschriften/Slogans] (http://stackoverflow.com/faq#signatures) –