0

这个问题的答案可能已经在网上了,但我不知道如何在没有得到不相关结果的情况下提问。在我使用 servlet 并具有web.xml部署描述符的 Java Web 项目中,除了 servlets 之外,是否有办法为任何URL 资源创建自定义映射?例如,html 文件、Javascript 文件、图像、样式表等?

我问的原因与浏览器缓存有关。在 Web 项目的版本之间,如果资源被缓存,然后更新推出,浏览器通常会首先尝试加载缓存的版本。在 DOM 元素和 Javascript 函数已更改或更新的地方,这可能会导致更新的页面由于资源不同步而中断。

现在我听说了很多解决这个问题的方法:

  • 将 URL 参数查询字符串添加到所有资源。因此,index.html成为index.html?v=1.2在一个发布中,然后index.html?v=1.3在发布之后,防止缓存重叠。我对此的担心是,并非所有浏览器都实现了尊重这一点的缓存策略。 问题:一个浏览器可能将文件缓存为index.html?v=1.3,另一个浏览器可能只是index.html在从缓存中加载文件后缓存并添加 URL 参数,而另一个浏览器可能根本不缓存带有 URL 参数的文件。
  • touch版本之间服务器上的所有文件。这样,当发送资源的 HTTP 请求,并且响应头显示检索到的文件的时间戳比缓存的时间戳更新时,它将重新加载。问题:同样,我不确定所有浏览器都实施任何此类缓存策略。
  • 在我的 Javascript 文件中实现所有版本必须匹配的逻辑,并使加载的第一个Javascript 文件成为提供主版本密钥的动态(不可缓存)文件。任何不同步的 javascript 文件(即版本与主版本不匹配,因为它已被缓存)将被强制重新加载。问题:这实际上听起来是个不错的方法,但是当我知道过去缓存一直是个问题时,依赖 Javascript 文件中添加的逻辑是很可怕的;比如,我的新“版本检查”逻辑会被加载吗?
  • 将版本与文件名合并。因此,index.html变为index.1.2.html。这将是万能的解决方案,因为缓存是在文件名级别完成的,当我们移动到 1.3 版时,浏览器不可能已经index.1.3.html缓存了。问题:开发端的源代码控制管理成为一场噩梦......

...除非,有一种方法可以映射index.1.3.html到简单命名的服务器端资源index.html。这又回到了我最初的问题,这可以在网络项目中完成吗?这甚至推荐吗?我知道web.xml,我们可以将 URL 模式映射到 servlet,但是我们可以将 URL 模式映射到其他资源吗?似乎在版本之间只维护一个描述符文件很容易,因此在客户端,似乎所有文件都是新的,所以第一次加载新版本时肯定会有加载命中,但是这样就可以消除缓存不同步的资源。

4

1 回答 1

0

在 Java Web 应用程序中,一个可行的简单解决方案实际上不需要映射,我也根本不需要更改web.xml部署描述符。相反,构建 Web 项目的方法只需要更改 ~ 这通常意味着更改构建脚本。将版本与文件名合并的一种稍微不同的方法是将版本与 URL 路径合并。例如,index.html对于 1.2 版,将在此处通过 HTTP 访问:

/doc-1.2/index.html

然后对于 1.3 版,可以在此处访问:

/doc-1.3/index.html
  • 在您的实际 Web 项目中(在 eclipse 中或您喜欢的任何地方), 的位置index.html以及所有其他 HTTP 资源将保持不变。这解决了源代码控制问题。
  • 在您的index.html文件中,所有特定于 Web 应用程序的资源都需要对于index.html. 当从服务器加载文件时,这消除了使用额外组件(例如 servlet)将版本号嵌入到每个引用的资源中的需要。
  • Web 应用程序的入口点,比如/(如http://hostname.domain.com/AppName/)将是一个 servlet,它根据当前版本重定向到实际入口点。例如,在 1.2 版中,入口点/(或index.jsp)将执行简单的重定向到doc-1.2/index.html,然后doc-1.3/index.html在 1.3 版中这将更改为。
  • 然而,无论是通过 Ant 还是 BuildForge 或任何工具构建 Web 应用程序,都必须修改构建脚本以将 Web 项目目录中的所有资源移动到构建 Web 应用程序WebContent的目标点。doc-<release #>

因此,在不同版本之间唯一需要改变的两件事是入口点重定向和构建脚本。如原始问题中所述,当部署新版本时,入口点现在会将客户端 Web 浏览器重定向到doc-1.3/index.html,并且所有资源现在都将相对于路径doc-1.3,并且浏览器不可能已经拥有任何东西以 . 为前缀缓存doc-1.3

此方法未解决的一个问题是,如果客户端在其浏览器中为版本相关资源添加书签,例如http://hostname.domain.com/AppName/doc-1.2/index.html,当最新版本为 1.3 时,会发生什么情况。他们最终会得到 404,因为在服务器上,不doc-1.2存在这样的目录(因为构建脚本只创建了当前版本所需的目录)。我能想到的解决这个问题的最简单的解决方案是制作一个额外的 servlet,并将所有以前的发行版本映射到它。servlet 将始终将用户重定向到实际入口点,或者将用户重定向到相同资源但在当前版本中。因此,当 Web 应用程序发布 1.5 时,“以前版本的重定向 servlet”将映射到所有/doc-1.0/**,/doc-1.1/**, /doc-1.2/**, /doc-1.3/**, and /doc-1.4/**(包括这些目录的所有子路径)。这个解决方案只需要在这个 servlet 映射中考虑和维护所有以前的版本。

于 2014-10-22T14:27:32.287 回答