Retrieve the port of the server on startup of servlet container (independent of server)

StackOverflow https://stackoverflow.com/questions/22872434

سؤال

I want to retreive the host and port of the server my Jersey 2.6 container is running in. The container is currently deployed on a Tomcat 7. However, I am forced to release my application deployable on every server which supports Java servlets. In this case, it's a Tomcat, but the solution must be server independent.

I have registered a Jersey startup class, where I want to fetch the host and port. However, I haven't found any solution to get the port yet.

My class, which is called when my Jersey servlet is initialized:

public class ServletInitialization extends ResourceConfig {
    public ServletInitialization() {
        int port    = ???;
        String host = InetAddress.getLocalHost().getHostName();
    }
}

On my researches, I have found a 3 year old question, which refers to the same problem. The accepted answer is focused on a tomcat and I think will only run on a Tomcat correctly (import org.apache.catalina.*). I would like to avoid to modify the server engine, the server configuration nor inject anything into the server on startup.

I have tried to use a plain Java servlet, but can't find a method to fetch the port there, too:

public class ServletInitializationPlain extends HttpServlet {

    @Override
    public void init() {
       int port = ???;  
    }   
}

Does someone have idea on how to retrieve the port out of a servlet container on startup (independant from the server it's running in)?


EDIT

I have accepted steohans solution, but I think it is quite tricky, why my ServletInitialization is not called on startup of the web container. Because actually ResourceConfig is not a Servlet. I will explain this issue now:

I have extended ResourceConfig.class, which is a subclass of an Application.class. This Application class is not an extended Java servlet, but an own class of Jersey. I though an Application is called on the startup of the web container. However, in the Jersey specification can be read, that the Application class needs to be itself handled by a ServletContainer.class which is a subclass of a Java Servlet. This handling is defined in the web.xml. And in the end, everything is a servlet here.

As it's not possible to get the port on startup, it's of course possible when a request is dispatched:

@Path("example")
public class ServletMethods {
    @GET
    public Response example(@HeaderParam("Host") String host) {
         return Response.ok(host).build();
    }
}
هل كانت مفيدة؟

المحلول 2

Preamble: Make sure to differentiate between a web container (also called servlet container) p.a. tomcat. And the Jersey ServletContainer class, which is just a servlet. (see javadoc)

Short: You can't, you can only get the listening port as soon as you have a request.

Long: One Servlet isn't bound to one specific Port, so there shouldn't be a function to retreive the listening port. (without container specific)

Your web container have the task to organize the listening, and don't even have to handle it by it self. For example you could also use apache to listen for requests, passing them to tomcat, which calls your Servlet. Also your web container don't have to listen at all, when your init function is called.

You could also tell tomcat to listen on tow different ports, giving the requests to the same Servlet. Look at this tutorial over tomcat connectors if you want to know more about this.

However as soon as you have a request, you know which port was used and you can use getLocalPort() from your HttpServletRequest to get the port.

نصائح أخرى

I found this answer and it works Get the server port number from tomcat with out a request

List<String> getEndPoints() throws MalformedObjectNameException,
        NullPointerException, UnknownHostException, AttributeNotFoundException,
        InstanceNotFoundException, MBeanException, ReflectionException {
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    Set<ObjectName> objs = mbs.queryNames(new ObjectName("*:type=Connector,*"),
            Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
    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) {
            String host = addr.getHostAddress();
            String ep = scheme + "://" + host + ":" + port;
            endPoints.add(ep);
        }
    }
    return endPoints;
}

Unfortunally, this only works for tomcat

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top