Question

In extension to this question is there a way to obtain the effective URL of a specific page in the same container from the scope of a ServletContextListener ?

A bit of background why I need this :

Within a fairly complex system I have setup a simple servlet to display the current information in JSON so I can display it easily on demand.

Now I want to go one step further and keep a historical record of this to see the evolution in time of these measurement points.

I have setup a simple ServletContextListener that starts up a thread to poll the same page at set interval and I can save the data to files that I can then read at a later time.

All is working fine, except that I have to manually specify the URL of the target page through configuration. If I could get this data programatically it would make one less configuration point that can go wrong. I figured it should not be too hard since everything stems from the same context but turns out it's apparently not so simple. Since everything is closely tied together and that thread is running on the server the host address can be hard coded to localhost. That said I still need to get the port and the base path of the webapp. From there I can take over since I know the structure within the webapp.

So... How can I get that info programatically and make life easier on the poor saps deploying the app later !

Was it helpful?

Solution

It is possible but it's not pretty and it will tie you to a specific container. In short it's a bit of a hack, YMMV. Solution below will work for Jetty.

Within the contextInitialize you can gain access to the WebAppContext like so :

public void contextInitialized(ServletContextEvent sce) {
    WebAppContext ctx = (WebAppContext) sce.getServletContext();
    System.out.println("context Base Path" + ctx.getContextPath());
    System.out.println("Getting the port is a bit trickier");
    System.out.println("One valid Port = " + ctx.getServer().getConnectors()[0].getPort());
}

I removed some checking and validation to be concise but this should suffice to get the idea... add dressing as required to your taste.

Here you will potentially get different answers with different executions. Since the goal is to call the service it matters little if we get the original declarations or an alias what counts is that the call succeed.

Lastly since the target IP address is known (localhost) as the worker thread is in the same JVM as the target address and the path to the service is known once I get inside the right context all we need is to know the port and context root path.

If you get to try this and have trouble please edit the answer or leave comments so we can all benefit from your experience.

OTHER TIPS

Not sure how to do it through the API.

But if you can afford to do this lazily, then my idea would be to install a filter that looks at the first request that comes in, retrieves the port/server that was used, and makes that info available in the Application scope.

Your ServletContextListener could then retrieve it from there?

But - as stated as a comment in that other question - you may have any number of "external" URLs or ports that map to your instance. But then I guess just knowing one is enough, so why not take the first one?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top