使用 JBoss 对静态内容进行自动版本控制
Posted
技术标签:
【中文标题】使用 JBoss 对静态内容进行自动版本控制【英文标题】:Auto-versioning of static content with JBoss 【发布时间】:2011-02-07 12:32:01 【问题描述】:根据 Q&A here,我想为在 JBoss 5 中运行的 Web 应用程序实现一个类似的自动版本控制系统。是否已经有任何东西可以做这种事情,或者我需要自己写点什么?明确一点:我没有使用 PHP。
对 php 了解不多,我不确定 PHP 的 .htaccess
等的 Tomcat/JBoss 类似物是什么。如果我必须编写自己的自动版本控制,我该从哪里开始?原理对我来说很清楚 - 使用文件的时间戳重写 URL,但我不太了解使用 JBoss/Tomcat 重写 URL。
更新:
结合Pascal 和novice 推荐的方法,我得到了以下结果:
1.自定义<my:script/>
和<my:style/>
标签,这样我就不必到处看到<c:url/>
标签了。
<%@ tag body-content="empty" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ attribute name="src" required="true" rtexprvalue="true" %>
<script src="<c:url value="$src" />"></script>
2. 非常接近新手的步骤,但在 web.xml 中将 UrlRewriteFilter
映射到 /*
:
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3. 将 CACHE_BUST 变量注入每个新会话(或多或少...),应用程序部署 timestamp:
// On application deploy:
long CACHE_BUST = System.currentTimeMillis() / 1000;
// later...
session.setAttribute("cacheBust", CACHE_BUST);
4. ...以便我可以在urlrewrite.xml
中使用这些规则:
<outbound-rule>
<from>^/static/(css|js|images)/(.*)$</from>
<to>%context-path/static/%session-attribute:cacheBust/$1/$2</to>
</outbound-rule>
<rule>
<from>^/static/\d10/(css|js|images)/(.*)$</from>
<to>/static/$1/$2</to>
</rule>
非常感谢 Pascal 和 novice 的帮助。
【问题讨论】:
【参考方案1】:以下解决方案更适合生产环境,因为您将增加每个版本的版本号。
方法:
将产品发布号(版本号)附加到jsp文件中的js/css/images/static内容url 浏览器会缓存 (js/css/static) 带有版本号的 url 文件 当新版本发布时,jsp文件中会有新版本号的js/css/static文件的url,所以浏览器会因为找不到新url的内容而进行调用李>步骤:
在类路径中包含urlrewritefilter.jar(从http://www.tuckey.org/urlrewrite/获取)使用 url 模式更新 web.xml,例如,
<filter>
<filter-name>urlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>urlRewriteFilter</filter-name>
<url-pattern>/v/*</url-pattern>
</filter-mapping>
更新 jsp 文件中的“abc.js”,例如,
<html>
<head>
<script type="text/javascript" src="<c:url value="/v/js/abc.js"/>"></script>
</head>
</html>
编写 urlrewritefilter.xml,例如,
<outbound-rule>
<from>^/v/(css|js|static)/(.*)$</from>
<to>%context-path/v/updateVersionNumberHere/$1/$2</to>
</outbound-rule>
<rule>
<from>^/v/updateVersionNumberHere/(css|js|static|images)/(.*)$</from>
<to>/$1/$2</to>
</rule>
说明:
jsp 提供给客户端时
jsp中提到的url: /v/js/abc.js 应用出站规则后: /contextPath/v/3.4.5/js/abc.js当浏览器调用 js/css/static 文件时
传入网址: /contextPath/v/3.4.5/js/abc.js 应用规则后: /js/abc.js积分:
浏览器会捕获带有 url /contextPath/v/3.4.5/js/abc.js 的 js 文件,接下来你部署一个新版本的 jsp 文件,它们可能有 url /contextPath/v/4.5.6/js /abc.js,所以浏览器会调用 js 文件而不是使用缓存的 js 文件。 如果您使用 maven 或类似的构建工具,版本更新可以自动进行【讨论】:
这看起来很有希望。将尽快测试。可能与@Pascal 的服务器启动时间建议结合使用。 写得很漂亮。谢谢!【参考方案2】:如果您不想在应用程序前面使用 Apache HTTPD,那么您可以使用自定义 servlet 过滤器或重用现有的 Url Rewrite Filter。这个过滤器基于 Apache 的mod_rewrite
并提供类似的功能。换句话说,它将允许实现与 PHP 相同的解决方案之一。
我以前见过 URL 重写过滤器。您能否详细说明我将如何使用它?我真的不清楚如何对这个问题应用过滤器,因为我不会完全调用包装在每个包含的 JS/CSS 文件周围的 JSP/JSTL 函数,而且我不知道如何获取从 WAR 中的文件修改的日期。
嗯,这个想法是模仿你链接到的答案的“PHP解决方案”(我们称之为选项1):
-
设置 URL 重写过滤器以将任何请求将
/css/my.123456.css
重写为 /css/my.css
实现一个Servlet
,它将为WAR内的给定资源获取File
对象,并将File#lastModified()
插入到该资源的返回路径中。
从 JSP 中为 CSS 调用 Servlet
。
另一种方法(选项 2)是将唯一的查询字符串附加到静态内容的 URL,例如服务器启动时间:
-
将服务器启动时间从
ServletContextListener
放在应用程序范围内(比如在键"key"
下)。
在你的 JSP 中
<link rel="stylesheet" type="text/css" href="/css/my.css?$key.startupTime">
Pro:不再需要重写 url。缺点:不太理想(内容将在重新启动时请求)但可以接受。
在网上搜索一些有助于实现选项 1 的步骤 #2 的代码时,我发现 Spring 的 o.s.w.s.ResourceServlet
正在做类似的事情,您可以查看它的源代码。但是,在更仔细地阅读它的 javadoc 时,我意识到这个 servlet 实际上正是您正在寻找的。像这样映射它:
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.ResourceServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
并将其applyLastModified
属性设置为true
。我对 javadoc 的理解是它应该可以解决问题。这是选项 3,如果添加对此 servlet 的依赖不是问题,这是 IMO 的最佳选择。
【讨论】:
我以前见过 URL 重写过滤器。您能否详细说明我将如何使用它?我真的不清楚如何对这个问题应用过滤器,因为我不会完全调用包装在每个包含的 JS/CSS 文件周围的 JSP/JSTL 函数,而且我不知道如何获取从 WAR 中的文件修改的日期。【参考方案3】:我们在网络应用中执行以下操作:
-
构建过程检索 Subversion 存储库编号并将其存储在 Web 应用程序的属性中。
构建过程还会为 WAR 中的静态资产创建一个目录结构,其中包含此修订号:/assets/1234/styles/...
过滤器/拦截器将资产路径(包括修订号)作为属性放入所有请求中
Jsp 模板使用此资产路径属性来构造资产的 URL
【讨论】:
这没什么用。就像我说的,我明白了原则;我正在寻找实现细节。 我不知道有什么“内置”专门处理这个问题。我上面描述的正是我们的实现,对我们来说已经足够好了。以上是关于使用 JBoss 对静态内容进行自动版本控制的主要内容,如果未能解决你的问题,请参考以下文章