在this question的扩展中,有没有办法从ServletContextListener的范围获取同一容器中特定页面的有效URL?
我需要这个的一些背景知识:
在一个相当复杂的系统中,我设置了一个简单的servlet来显示JSON中的当前信息,以便我可以根据需要轻松显示它。
现在我想更进一步,保留历史记录,看看这些测量点的时间演变。
我已经设置了一个简单的ServletContextListener,它启动一个线程以设置的间隔轮询同一页面,我可以将数据保存到以后可以读取的文件中。
一切正常,但我必须通过配置手动指定目标页面的URL。如果我能以编程方式获取此数据,那么可能会减少一个可能出错的配置点。我认为它不应该太难,因为一切都源于相同的背景,但事实证明它显然不是那么简单。由于所有内容都紧密相连,并且该线程在服务器上运行,因此主机地址可以硬编码到localhost。也就是说我仍然需要获得webapp的端口和基本路径。从那里我可以接管,因为我知道webapp中的结构。
所以...我怎样才能以编程方式获取这些信息,让以后在部署应用程序的糟糕小屋中让生活更轻松!
答案 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或端口映射到您的实例。但是我想只知道一个就足够了,为什么不拿第一个呢?