如何查询 servlet 容器以从 ServletContextListener 获取有效 URL?

New*_*ian 2 java url port jetty servlet-listeners

作为这个问题的扩展,有没有办法从 ServletContextListener 的范围内获取同一容器中特定页面的有效 URL?

为什么我需要这个的一些背景:

在一个相当复杂的系统中,我设置了一个简单的 servlet 来显示 JSON 中的当前信息,这样我就可以根据需要轻松地显示它。

现在我想更进一步,保留一份历史记录,以查看这些测量点的时间演变。

我已经设置了一个简单的 ServletContextListener,它启动一个线程以按设定的时间间隔轮询同一个页面,我可以将数据保存到文件中,然后我可以在以后读取。

一切正常,除了我必须通过配置手动指定目标页面的 URL。如果我能以编程方式获取这些数据,那么会减少一个可能出错的配置点。我认为它不应该太难,因为一切都源于相同的上下文,但事实证明它显然没有那么简单。由于一切都紧密联系在一起并且该线程在服务器上运行,因此主机地址可以硬编码到本地主机。也就是说,我仍然需要获取 webapp 的端口和基本路径。从那里我可以接手,因为我知道 webapp 中的结构。

所以......我怎样才能以编程方式获取该信息,并让稍后部署应用程序的可怜的 sap 的生活更轻松!

New*_*ian 5

这是可能的,但它并不漂亮,它会将您绑定到特定的容器。简而言之,这有点像黑客攻击,YMMV。下面的解决方案适用于 Jetty。

在 contextInitialize 中,您可以像这样访问 WebAppContext:

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());
}
Run Code Online (Sandbox Code Playgroud)

为了简洁起见,我删除了一些检查和验证,但这应该足以让您了解这个想法……根据您的口味添加调味品。

在这里,您可能会通过不同的执行获得不同的答案。由于目标是调用服务,因此我们是否获得原始声明或别名无关紧要,重要的是调用成功。

最后,由于目标 IP 地址是已知的(本地主机),因为工作线程与目标地址在同一个 JVM 中,并且一旦我进入正确的上下文,服务的路径就是已知的,我们只需要知道端口和上下文根小路。

如果您尝试此操作并遇到问题,请编辑答案或发表评论,以便我们都能从您的经验中受益。