【问题标题】:Finding your application's URL with only a ServletContext仅使用 ServletContext 查找应用程序的 URL
【发布时间】:2010-10-15 02:43:51
【问题描述】:

我正在使用 Spring MVC 编写一个 Java Web 应用程序。我有一个后台进程,它遍历数据库并找到必须通过电子邮件发送给我的用户的通知。这些电子邮件消息需要包含指向应用程序的超链接。对于网络应用来说,这似乎是一种相当常见的模式,但我遇到了麻烦。

如何使用服务器名称和上下文路径派生我的应用程序的完全限定 URL?我无权访问 HttpServletRequest 中的任何方法,因为我将其作为后台进程运行,而不是响应 Web 请求。我能做的最好的就是访问 ServletContext。

目前我将基本 URL 放入配置文件并在启动时读取它,但此应用程序将获得许可并部署到客户的应用程序服务器,如果可能的话,我希望他们不必配置这个是手动的。

【问题讨论】:

  • 为什么不能使用相对 URL?
  • 相对于什么?这是通过电子邮件发送的。
  • 啊,如果它是通过电子邮件发送出去的,那么你当然需要一个完整的路径。我想这可能是 Servlet 的一部分——启动后台任务的东西。
  • 这也让我发疯了,尝试使事情变得相对很好,但是在某些情况下您必须能够发布完整路径。我目前正在与一个愚蠢的系统作斗争,该系统需要一条完整的路径来配置其所有事物的 servlet。在我看来这很糟糕,因为它阻止了创建可重定位的 WAR。我希望这个问题的一个好的答案能让我从外面修补它。

标签: java jakarta-ee spring-mvc


【解决方案1】:

我认为你可以使用类似的东西:

String host = InetAddress.getLocalHost().getCanonicalHostName();
String appUrl = String.format("http://%s:%s%s", host, port, contextPath);

使用来自 ServletContext 的端口和 contextPath。

【讨论】:

  • 不要这样做。我非常怀疑您的用户会通过本地主机地址访问应用程序。
【解决方案2】:

【讨论】:

  • 上下文路径不返回完全限定的 url。例如,如果您的完整网址是 www.google.com/v7,那么 getContextPath() 将返回“/v7”。因此,为了帮助其他人,这并不能回答问题,尽管对于阅读错误问题并试图获取上下文路径的人们仍然可能有所帮助。
  • @TheJeff 负载平衡器和代理应该被提及。他们使获取 protocol/host/port 毫无意义。您可以跳转解析专有标头,但只有getContextPath() 部分是可靠的,除非途中有一些重写))
【解决方案3】:

不建议在运行时动态准备 URL,尤其是基于 ServletRequest。这主要是因为您不知道用户将用于访问应用程序的 URL - 应用程序服务器可能位于 Web 服务器、防火墙或负载平衡器后面。简而言之,我们无法预测网络拓扑。

您当前从属性文件中获取 URL 的技术足以解决上述问题。也许您应该考虑提供一个管理控制台来管理出现在邮件中的 URL,特别是如果有一个管理控制台,或者如果有相关的选项应该进入其中。

编辑:我的最后一点与托尼所说的相呼应。

【讨论】:

    【解决方案4】:

    如果配置文件不存在(例如在 WEB-INF 文件夹中),为什么在第一次运行应用程序时没有设置网页。使用 ServletContext,您可以调用 getRealPath 并获取真实路径一个文件,看看它是否存在()。如果存在,则重定向到应用程序起始页,如果不存在,则打开管理页面。

    你可以用 ServletContext 做的最好的事情是从 web.xml 中读取一些设置,并获取上下文路径,只有 HttpRequest 可以给你 FQ URL。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 2011-09-23
    相关资源
    最近更新 更多