Obtenir le numéro de port du serveur de tomcat sans demande

Existe-t-il une API ou une configuration Tomcat disponible qui puisse indiquer à une application (probablement au démarrage), sur quel port elle tourne sans demande?

Imaginez un scénario où il y a deux applications Web fonctionnant dans le même Tomcat et dont l'une doit invoquer un service web de l'autre. Nous ne voulons pas que la requête quitte le Tomcat (si vous utilisez le nom du serveur Apache ou L'URL absolue, la requête sortira et reviendra et pourra aller à toute instance) et revenir en. Pour cela je connais le nom de la machine mais aucun moyen d'obtenir le numéro de port. Je sais que je peux coder ces informations mais je ne veux pas le faire car je veux que mon fichier war soit agnostique au niveau du serveur d'application.

je sais que nous pouvons le trouver si nous avons une requête Httpservlet151920920"

cela ne fonctionne que pour Tomcat 6 et ne fonctionnera pas sur Tomcat 7

28
demandé sur SiHa 2010-10-05 23:53:30

11 réponses

avec ceci:

List<String> getEndPoints() throws MalformedObjectNameException,
        NullPointerException, UnknownHostException, AttributeNotFoundException,
        InstanceNotFoundException, MBeanException, ReflectionException {
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    QueryExp subQuery1 = Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"));
    QueryExp subQuery2 = Query.anySubString(Query.attr("protocol"), Query.value("Http11"));
    QueryExp query = Query.or(subQuery1, subQuery2);
    Set<ObjectName> objs = mbs.queryNames(new ObjectName("*:type=Connector,*"), query);
    String hostname = InetAddress.getLocalHost().getHostName();
    InetAddress[] addresses = InetAddress.getAllByName(hostname);
    ArrayList<String> endPoints = new ArrayList<String>();
    for (Iterator<ObjectName> i = objs.iterator(); i.hasNext();) {
        ObjectName obj = i.next();
        String scheme = mbs.getAttribute(obj, "scheme").toString();
        String port = obj.getKeyProperty("port");
        for (InetAddress addr : addresses) {
            if (addr.isAnyLocalAddress() || addr.isLoopbackAddress() || 
                addr.isMulticastAddress()) {
                continue;
            }
            String host = addr.getHostAddress();
            String ep = scheme + "://" + host + ":" + port;
            endPoints.add(ep);
        }
    }
    return endPoints;
}

vous obtiendrez une liste comme celle-ci:

[http://192.168.1.22:8080]
23
répondu ggrandes 2017-04-26 12:18:18

pour quiconque s'intéresse à la façon dont nous avons résolu ce problème, voici le code simulé

Server server = ServerFactory.getServer();
        Service[] services = server.findServices();
        for (Service service : services) {
            for (Connector connector : service.findConnectors()) {
                ProtocolHandler protocolHandler = connector.getProtocolHandler();
                if (protocolHandler instanceof Http11Protocol
                    || protocolHandler instanceof Http11AprProtocol
                    || protocolHandler instanceof Http11NioProtocol) {
                    serverPort = connector.getPort();
                    System.out.println("HTTP Port: " + connector.getPort());
                }
            }


        }
20
répondu Teja Kantamneni 2011-07-22 18:50:04
public void getIpAddressAndPort() 
throws MalformedObjectNameException, NullPointerException,
            UnknownHostException {

        MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();

        Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"),
                Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));

        String host = InetAddress.getLocalHost().getHostAddress();
        String port = objectNames.iterator().next().getKeyProperty("port");

        System.out.println("IP Address of System : "+host );
        System.out.println("port of tomcat server : "+port);

    }
3
répondu Arun Maharana 2016-08-12 09:47:41

le numéro de port du serveur n'existe pas. Il peut avoir n'importe quel nombre de numéros de port. Donc, ce que vous demandez n'a pas de sens. le numéro de port associé à une requête spécifique fait logique.

1
répondu user207421 2010-11-18 01:08:24
  • Obtenir MBean/JMX Objet pour Tomcat/Instance de Serveur
  • Obtenir de l'Instance de Serveur Virtuel des Données Liées à la il y

Check http://svn-mirror.glassfish.org/glassfish-svn/tags/embedded-gfv3-prelude-b07/web/web-glue/src/main/java/com/sun/enterprise/web/WebContainer.java pour référence

le contenu du MBeanServer peut alors être exposé à travers divers protocoles, mis en œuvre par le protocole connecteurs[RMI/IIOP], ou protocole de cartes[SNMP/HTTP] . Dans ce cas, L'utilisation de l'adaptateur SNMP sera une meilleure approche de sorte qu'un piège SNMP peut être placé sans connaître L'adresse IP/port exacte d'autres serveurs D'Application

1
répondu Puspendu Banerjee 2010-11-20 20:45:31

ces types de serveurs sont conçus pour pouvoir écouter sur des ports (presque) arbitraires et pour cacher ces détails aux applications contenues qui normalement n'ont pas besoin de savoir.

la seule façon est de lire les fichiers de configuration vous-même et ont accès aux arguments en ligne de commande qui ont démarré le serveur où les fichiers de configuration peuvent avoir été dépassés. Vous devez en savoir beaucoup sur le système que vous utilisez pour cela travailler. Il n'y a aucun moyen de le faire de façon valable.

même s'il y en avait, il y a des cas où cela n'a tout simplement pas d'importance comme d'être derrière un NAT, certains pare-feu, etc.

1
répondu Allen 2010-11-21 20:23:55

vous pouvez utiliser crossContext . Mais je ne pense pas que le serveur d'application agnostique.

je partagerais une classe personnalisée, se comportant comme un registre d'applications en cours d'exécution dans la même instance tomcat à travers JNDI, comme je l'ai expliqué ici .

pendant le démarrage, par le biais d'un ContextListener ou par le biais D'un événement de conteneur de printemps, j'obtiendrais le registre par le biais d'une recherche JNDI, j'ajouterais mon instance d'application web avec une url obtenu à partir du servletcontext.contextpath, et enfin enregistrer un auditeur pour entendre d'autres applications s'enregistrer. C'est le plus agnostique serveur que je puisse penser.

obtenir le port ne sera pas agnostique au niveau du serveur, vous devez utiliser un paramètre contextuel.

EDIT: je suis désolé, j'ai oublié de dire que ce que j'ai décrit est de partager des objets entre des contextes, mais non, vous ne pouvez pas ne pas connaître le port à moins d'utiliser une API de Serveur (pas agnostique du tout).

1
répondu mschonaker 2017-05-23 12:10:08

Je ne suis pas entièrement sûr si vous pouvez accéder au port Tomcat à partir du code dans la configuration d'environnement dont vous avez besoin. Avez-vous considéré réellement avoir L'URL complète du service web passé comme un paramétrage de configuration param/(probablement dans un .fichier de propriétés) de l'application?

de cette façon, vous n'auriez pas à hardcode le port et de-couple à la fois vos applications afin que vous puissiez techniquement avoir le service web sur un tomcat externe, mais encore y accéder en changeant simplement le propriété, éviter la reconstruction du code.

0
répondu Sarat 2010-10-05 21:22:58

précédemment sur un grand projet distribué, la conception que j'ai utilisée était de faire initialiser les services centralisés avec L'URL(& port) du service central.

cela signifie évidemment que le service central doit maintenir une liste des services (URL & port) à initialiser.

0
répondu Ashley Walton 2010-11-16 11:46:46

Si vous voulez accéder à une application sur la même instance de serveur, juste omettre la partie serveur de l'URL. Quelques exemples de ce que vous pouvez réaliser. Le document actuel est à http://example.com:8080/app2/doc.html

  • xxx.html devient http://example.com:8080/app2/xxx.html
  • ../xxx.html devient http://example.com:8080/xxx.html
  • ../xxx.html devient http://example.com:8080/xxx.html
  • ../foo/xxx.html devient http://example.com:8080/foo/xxx.html
  • ../../xxx.html devient http://example.com:8080/xxx.html (il n'y a aucun moyen d'aller au-delà de la racine)
  • /xxx.html devient http://example.com:8080/xxx.html C'est probablement ce que vous recherchez.
  • //other.com/xxx.html devient http://example.com:8080/xxx.html utile si vous voulez garder" https: "
0
répondu Aaron Digulla 2010-11-19 14:16:00

Hmm, comment une application peut-elle démarrer dans Tomcat sans demande? Peut-être que je vais être en mort cérébrale pendant un moment, mais je ne pense pas que les cours se chargeront tant qu'une requête n'aura pas été reçue. Bien sûr, vous pourriez avoir des cours indépendants de n'importe quelle requête particulière, mais ils auraient besoin d'une requête pour les faire virer à un moment donné.

-1
répondu Jay 2010-10-05 20:42:37