Получить номер порта сервера от tomcat без запроса
есть ли какой-либо API Tomcat или конфигурация, которая может сказать приложению (возможно, при запуске), какой порт работает без запроса?
представьте себе сценарий, в котором есть два веб-приложения, запущенные в одном Tomcat, и одно из которых должно вызвать веб-службу из другого. Мы не хотим, чтобы запрос покидал Tomcat (если вы используете имя сервера Apache или абсолютный URL-адрес, запрос выйдет и вернется снова, и он может перейти в любой экземпляр) и вернуться. Для этого я знаю имя машины, но не могу получить номер порта. Я знаю, что могу жестко закодировать эту информацию, но я не хочу делать это, как я хочу мой war
файл будет агностиком сервера приложений.
Я знаю, что мы можем найти его если у нас есть HTTPServletRequest
это работает только для Tomcat 6 и не будет работать на Tomcat 7
11 ответов
С этого:
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;
}
вы получите список такой:
[http://192.168.1.22:8080]
для всех, кто заинтересован в том, как мы решили это, вот макет кода
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());
}
}
}
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);
}
на номер порта сервера не существует. Он может иметь любое количество портов. То, о чем ты просишь, не имеет смысла. на номер порта, связанный с конкретной просьбой тут смысла.
- получить объект MBean/JMX для экземпляра Tomcat / Server
- получить данные, связанные с экземпляром виртуального сервера оттуда
проверить http://svn-mirror.glassfish.org/glassfish-svn/tags/embedded-gfv3-prelude-b07/web/web-glue/src/main/java/com/sun/enterprise/web/WebContainer.java Для справки
контент MBeanServer затем может быть выставлен через различные протоколы, реализованные протоколом разъемы[RMI / IIOP], или адаптеры протокола[SNMP / HTTP]. В этом случае использование SNMP-адаптера будет лучшим подходом, так что SNMP trap можно разместить, не зная точного IP / порта других серверов приложений
эти типы серверов разработаны, чтобы иметь возможность прослушивать (почти) произвольные порты и скрывать эти данные от содержащихся приложений, которые обычно не нужно знать.
единственный способ-прочитать файлы конфигурации самостоятельно и иметь доступ к аргументам командной строки, запустил сервер, где файлы конфигурации могут быть переопределены. Вы должны много знать о системе, в которой вы работаете, чтобы это работало. Это невозможно. делать это сносно.
даже если бы были, есть случаи, когда это просто не имеет значения, как быть за NAT, определенные брандмауэры и т. д.
можно использовать crossContext. Но я не думаю, что это агностик сервера приложений.
Я бы поделился пользовательским классом, действуя как реестр запущенных приложений в том же экземпляре tomcat через JNDI, как я объяснил здесь.
во время запуска, через ContextListener
или через событие Spring container я бы получил реестр через поиск JNDI, добавьте мой экземпляр веб-приложения с url-адресом, полученным из servletcontext.самом contextpath, и, наконец, зарегистрировать слушателя, чтобы услышать другие приложения, регистрирующие себя. Это больше серверный агностик, который я могу придумать.
получение порта не зависит от сервера, вы должны использовать параметр контекста.
EDIT: извините, забыл сказать, что то, что я описал, - это совместное использование объектов среди контекстов, но нет, вы не можете не знать порт, если вы не используете какой-то серверный API (не агностик вообще).
Я не совсем уверен, что вы можете получить доступ к порту Tomcat из кода в конфигурации среды, которая вам нужна. Рассматривали ли вы на самом деле полный URL-адрес веб-службы, переданный как параметр/параметр конфигурации (возможно, в a .файл свойств) в приложение?
таким образом, вам не придется жестко кодировать порт и де-пару обоих ваших приложений, чтобы вы могли технически иметь веб-службу на внешнем tomcat, но все равно получить к нему доступ, просто изменив свойство, избегая перестройка кода.
ранее в большом распределенном проекте я использовал дизайн, чтобы централизованная служба инициализировала несколько служб с URL-адресом Центральной службы (&port).
очевидно, это означает, что Центральная служба должна поддерживать список служб (URL & port) для инициализации.
если вы хотите получить доступ к приложению на том же экземпляре сервера, просто опустить серверную часть URL. Несколько примеров того, чего можно достичь. Текущий документ находится на http://example.com:8080/app2/doc.html
-
xxx.html
становитсяhttp://example.com:8080/app2/xxx.html
-
../xxx.html
становитсяhttp://example.com:8080/xxx.html
-
../xxx.html
становитсяhttp://example.com:8080/xxx.html
-
../foo/xxx.html
становитсяhttp://example.com:8080/foo/xxx.html
-
../../xxx.html
становитсяhttp://example.com:8080/xxx.html
(нет никакого способа выйти за пределы корня) -
/xxx.html
становитсяhttp://example.com:8080/xxx.html
это, вероятно, то, что вы ищете. -
//other.com/xxx.html
становитсяhttp://example.com:8080/xxx.html
полезно, если вы хотите сохранить " https:"
Хм, как приложение будет запускаться в Tomcat без запроса? Может быть, у меня на мгновение отключится мозг, но я не думаю, что какие-либо занятия будут загружаться, пока не поступит запрос. Конечно, у вас могут быть классы, независимые от любого конкретного запроса, но им понадобится запрос, чтобы их уволили в какой-то момент.