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

时间:2011-12-12 10:31:44

标签: java url jetty port servlet-listeners

this question的扩展中,有没有办法从ServletContextListener的范围获取同一容器中特定页面的有效URL?

我需要这个的一些背景知识:

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

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

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

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

所以...我怎样才能以编程方式获取这些信息,让以后在部署应用程序的糟糕小屋中让生活更轻松!

2 个答案:

答案 0 :(得分:4)

这是可能的,但它不漂亮,它会将你绑定到一个特定的容器。简而言之,这是一个黑客,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());
}

我删除了一些检查和验证以简洁,但这应该足以获得想法...根据您的口味添加敷料。

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

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

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

答案 1 :(得分:1)

不确定如何通过API完成。

但如果你能负担得起懒惰,那么我的想法是安装一个过滤器,查看第一个请求,检索所使用的端口/服务器,并制作应用程序范围内提供的信息。

然后你的ServletContextListener可以从那里检索它吗?

但是 - 正如其他问题中的评论所述 - 您可能有任意数量的“外部”URL或端口映射到您的实例。但是我想只知道一个就足够了,为什么不拿第一个呢?