Is there any Tomcat API or configuration available which can tell an application (probably on startup), what port its running on without a request?
Imagine a scenari
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);
}
The server port number doesn't exist. It can have any number of port numbers. So what you're asking doesn't make sense. The port number associated with a specific request does make sense.
I am not entirely sure if you can access the Tomcat port from code in the environment configuration you need. Did you consider actually having the full URL to the web service passed as a configuration param/setting (probably in a .properties file) to the app?
This way you wouldn't have to hardcode the port and de-couple both your apps so that you could technically have the web service on an external tomcat but still access it by just changing the property, avoiding code re-build.
These types of servers are designed to be able to listen on (almost) arbitrary ports and to hide these details from the contained applications which normally do not need to know.
The only way is to read the configuration files yourself and have access to the command line arguments that started the server where the configuration files may have been overridden. You have to know a lot about the system you are running on for this to work. There is no way of doing it portably.
Even if there were, there are cases in which it simply does not matter like being behind a NAT, certain firewalls, etc.
public String getPort() {
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
Set<ObjectName> objectNames;
try {
objectNames = beanServer.queryNames(new ObjectName("*:type=ProtocolHandler,*"),
Query.match(Query.attr("name"), Query.value("\"http-*")));
} catch (MalformedObjectNameException e) {
LOGGER.error("Port not defined!", e);
}
return objectNames.iterator().next().getKeyProperty("port");
}
public String getSecurePort() {
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
Set<ObjectName> objectNames;
try {
objectNames = beanServer.queryNames(new ObjectName("*:type=ProtocolHandler,*"),
Query.match(Query.attr("name"), Query.value("\"https-*")));
} catch (MalformedObjectNameException e) {
LOGGER.error("SecuredPort not defined!", e);
}
return objectNames.iterator().next().getKeyProperty("port");
}
If you want to access an application on the same server instance, just omit the server part of the URL. Some examples what you can achieve. The current document is at http://example.com:8080/app2/doc.html
xxx.html
becomes http://example.com:8080/app2/xxx.html
../xxx.html
becomes http://example.com:8080/xxx.html
../xxx.html
becomes http://example.com:8080/xxx.html
../foo/xxx.html
becomes http://example.com:8080/foo/xxx.html
../../xxx.html
becomes http://example.com:8080/xxx.html
(there is no way to go beyond the root)/xxx.html
becomes http://example.com:8080/xxx.html
This is probably what you look for.//other.com/xxx.html
becomes http://example.com:8080/xxx.html
Useful if you want to keep "https:"