2009-11-13 5 views
10

Tomcat offre une prise en charge de «Virtual Hosting»: un moteur/application Web peut être configuré pour être responsable d'une liste de domaines. Ces domaines doivent être placés dans les fichiers server.xml/context.xml avec une directive xml spéciale.Tomcat: Modifier les hôtes virtuels par programme?

=> Est-il possible de modifier la configuration de Tomcat (en général) et en particulier les "hôtes virtuels" d'une application Web/moteur par programme?

Par exemple, si un nouvel utilisateur s'inscrit, je dois ajouter son domaine à la liste des "hôtes/domaines virtuels acceptés". La seule façon dont je pense actuellement est de changer les fichiers xml via un script, puis redémarrer Tomcat.

Y a-t-il un moyen de les ajouter ajouter du temps d'exécution via certaines méthodes Java par programme?

Merci beaucoup! Jan

Répondre

6

Tomcat fournit des API pour créer un nouvel hôte virtuel. Pour accéder à l'objet wrapper nécessaire pour cela, vous devez implémenter un ContainerServlet. Vous pouvez créer hôte virtuel comme celui-ci,

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

Vous devez vous assurer répertoire appBase existe et vous devez trouver des moyens Persister le nouvel hôte à la server.xml ou vous perdez l'hôte au redémarrage.

Cependant, cette approche fonctionne rarement. Si vos utilisateurs exécutent leurs propres applications, vous souhaitez vraiment exécuter des instances distinctes de Tomcat afin de pouvoir mieux partager les applications. par exemple. Une application à court de mémoire ne tue pas toutes les autres applications.

Si vous fournissez l'application, vous pouvez simplement utiliser un hôte (defaultHost). Vous pouvez obtenir le nom de domaine à partir de Host en-tête et faire ce que vous voulez dans votre code.

+1

Bonjour ZZ Coder, merci pour votre réponse. C'est vraiment intéressant, jamais entendu parler de ça, c'est génial de savoir qu'il y a des façons d'accéder à l'hôte et au moteur de Tomcat. – jan

+0

@Coder, comment obtenir l'objet 'wrapper' – Kainix

+0

@Kainix Vous devez créer une servlet implémentant ContainerServlet, qui a un setter setrapper(). Tomcat appellera votre setter pour définir le wrapper. Je n'ai pas utilisé cela depuis Tomcat 5 donc le mécanisme a peut-être changé. –

1

Je vous suggère de définir votre application comme hôte virtuel par défaut dans le fichier server.xml afin que votre hôte virtuel unique puisse répondre aux demandes adressées à un nom d'hôte. Tomcat est fourni avec l'application localhost définie en tant qu'hôte virtuel par défaut. Vous pouvez donc voir comment procéder en inspectant simplement le fichier server.xml d'une installation de vanilla tomcat. Vous pouvez déterminer par programme le nom d'hôte auquel l'utilisateur a envoyé la demande à l'aide de la méthode ServletRequest.getServerName().

Tomcat était livré avec une application Web appelée "gestionnaire d'hôte". Note: ceci est différent de l'application web "manager" qui vient encore avec Tomcat. Le gestionnaire d'hôte permet de modifier la configuration ou d'ajouter de nouveaux hôtes virtuels à la volée sans redémarrer le serveur. Vous pouvez interagir avec le gestionnaire d'hôte via HTTP (par programme si vous le souhaitez). Cependant, il a eu la fâcheuse faille de ne pas avoir validé ses changements à server.xml afin qu'ils aient tous été perdus lors du redémarrage d'un serveur web. Pour une raison quelconque, à compter de la version 6, Tomcat n'est plus fourni avec l'application hôte-gestionnaire. Donc, il ne semble plus être supporté.

+0

Bonjour Asaph, je vous remercie beaucoup pour votre réponse! – jan

3

Vous ne devez pas modifier l'environnement du serveur par programmation et il n'existe aucun moyen fiable et standard de le faire. Le mieux est de faire et de tout garder du côté webapp. Pour commencer, un Filter est parfaitement adapté pour cela. Stockez les noms quelque part dans une table de base de données ou un fichier de propriétés que vous mettez en cache dans la portée de l'application. Vérifiez le HttpServletRequest#getRequestURI() (ou le getServerName() s'il s'agit d'un sous-domaine au lieu de pathinfo) et effectuez la tâche de transfert en conséquence.

Espérons que cela aide.

+0

Bonjour BalusC, merci beaucoup pour votre réponse! – jan

+0

Je pense que c'est la meilleure façon de le faire. Pourquoi existe-t-il une cartographie db nécessaire. Ne pouvons-nous pas simplement faire correspondre l'application Web au sous-domaine? – Sorter

3

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

Si nécessaire, récupérer l'objet hôte et de travailler avec elle:

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

Merci pour votre message! Merci de ne pas utiliser les signatures/slogans dans vos messages. Votre boîte utilisateur compte comme votre signature, et vous pouvez utiliser votre profil pour publier toute information sur vous que vous aimez. [FAQ sur les signatures/slogans] (http://stackoverflow.com/faq#signatures) –

Questions connexes