10
votes

Tomcat: Changez les hôtes virtuels par programme?

TOMCAT propose une prise en charge "Hébergement virtuel": Un moteur / application Web peut être configuré pour être responsable d'une liste de domaines. Ces domaines doivent être mis dans les fichiers server.xml / context.xml avec une directive spéciale XML.

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

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

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

Merci beaucoup! Jan


0 commentaires

5 Réponses :


1
votes

Je vous suggère de définir votre application pour être l'hôte virtuel par défaut dans Server.XML afin que votre hôte virtuel unique puisse répondre aux demandes adressées à n'importe quel nom d'hôte. Tomcat est expédié avec l'application localhost définie comme hôte virtuel par défaut. Vous pouvez donc voir comment procéder en inspectant simplement le fichier Server.xml d'une installation Vanilla Tomcat. Vous pouvez déterminer de manière programmative le nom d'hôte que l'utilisateur a envoyé la demande à l'aide de la servletrequest.getservername () méthode.

Tomcat utilisé pour expédier avec une application Web appelée "Host-Manager". Remarque: Ceci est différent de celui de la "application" gestionnaire "qui vient toujours avec Tomcat. Host Manager a permis 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 hôte via HTTP (de manière programmatique si désiré). Cependant, il a eu la faille malheureuse de ne pas avoir commis de modifications à Server.XML, elles étaient donc toutes perdues sur un redémarrage du serveur Web. Pour une raison quelconque, en commençant par la version 6, Tomcat n'est plus expédié avec l'application Host-Manager. Donc, il ne semble plus être pris en charge.


0 commentaires

3
votes

Vous ne devriez pas changer l'environnement du serveur par programme et il n'y a pas de façons fiables et standard de le faire. Le mieux est de faire et de tout garder sur le côté WebApp. Pour démarrer, un filtre convient parfaitement à 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 getervername () S'il s'agit d'un sous-domaine au lieu de pathinfo) et faites la tâche de transfert en conséquence.

J'espère que cela aide.


1 commentaires

Je pense que c'est la meilleure façon de le faire. Pourquoi y a-t-il une cartographie de la DB nécessaire. Pouvons-nous ne pas simplement mapper l'application Web sur le sous-domaine?



8
votes

Tomcat fournit aux API pour créer un nouvel hôte virtuel. Pour accéder à l'objet Wrapper nécessaire pour cela, vous devez implémenter un conteneur d'accord. Vous pouvez créer un 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);


8 commentaires

Bonjour Coder ZZ, merci pour votre réponse. C'est très intéressant, jamais entendu parler de cela, c'est brillant de savoir qu'il existe des moyens d'accéder à l'hôte et à la motque à Tomcat.


@Coder, comment obtenir wrapper objet


@KAINIX Vous devez créer un servlet mettant la mise en œuvre de conteneur d'entretien, qui a un setter setTraper (). Tomcat appellera votre setter pour définir l'emballage. Je n'ai pas utilisé cela depuis Tomcat 5 afin que le mécanisme ait peut-être changé.


@Coder, j'ai implémenté le répertoire conteneurservlet créé (code> APLBASE étant donné que je teste plus localement j'ai ajouté le nom dans mon hosts < / Code> Fichier dans / Pilotes / etc / hosts Mais lorsque je l'exécute, mettez ce domainName dans le navigateur, il donne une page vierge. Est-ce que je manque quelque chose?


Puis-je demander si cela écrit également au fichier physique serveur.xml? La mise à jour sera-t-elle partie après un redémarrage?


@Kainix j'ai le même problème


@Soheilrahsaz Je n'ai pas réussi à faire cela, même après avoir suivi la suggestion du codeur. Faites-nous savoir si vous avez un succès.


@Kainix je l'ai fait et posté le résultat ici.



3
votes

Utilisez JMX

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


1 commentaires

Merci pour votre message! Veuillez ne pas utiliser de signatures / taglines dans vos messages. Votre boîte utilisateur compte comme signature et vous pouvez utiliser votre profil pour publier toutes les informations sur vous-même. FAQ sur Signatures / Taglines



1
votes

à résumer zz coder code> réponse qui m'a guidé beaucoup:

Vous devez créer un servlet qui implémente conteneurservlet code> et remplacement setwrapper code > Méthode pour obtenir le org.apache.catalina.wrapper code> objet. p>

pour cela, vous devez avoir privilégié = "vrai" code> dans votre context.xml code> contexte code> tag ou il lancera une exception. Ensuite, vous pouvez utiliser l'objet wrapper code> et: p>

StandardContext context = (StandardContext) wrapper.getParent();
StandardHost currentHost = (StandardHost) context.getParent();
StandardEngine engine = (StandardEngine) currentHost.getParent();

StandardHost host = new StandardHost();
host.setAppBase(currentHost.getAppBase()); //in my case I created another instance of the same application
host.setDomain(currentHost.getDomain());
host.setAutoDeploy(false); // not restarting app whenever changes happen
host.setName("domain.com");
host.setThrowOnFailure(true);// tell it to throw an exception here if it fails to create the host
host.setDeployOnStartup(true);
host.setStartChildren(true);
host.setParent(engine); 
// you can add multiple aliases
host.addAlias(alias);

StandardContext ctx = new StandardContext();
ctx.setDocBase(context.getDocBase()); //again I reused my same application setting
ctx.setPath("");
if(currentHost.getWorkDir() != null)
{//create a working directory based on your new host's name
    ctx.setWorkDir(currentHost.getWorkDir().replace(currentHost.getName(), host.getName()));
}
ctx.setName(host.getDomain());

//some extra config that you can use
ctx.setUseHttpOnly(false);
ctx.setReloadable(false);
ctx.setXmlValidation(false);
ctx.setXmlNamespaceAware(false);
ctx.setCrossContext(false);
ctx.setParent(host);
// you have to have this or it will not work!!
ctx.addLifecycleListener(new ContextConfig()); 

//you can also create resources and add it to the context like so:
final ContextResource res = new ContextResource();
res.setName("name");
res.setAuth("Container");
res.setType("javax.sql.DataSource");
ctx.getNamingResources().addResource(res);

host.addChild(ctx);

engine.addChild(host);


0 commentaires