使用JBoss自动版本化静态内容

时间:2010-04-13 15:32:44

标签: tomcat caching jboss auto-versioning

根据Q& A here,我想为在JBoss 5中运行的Web应用程序实现类似的自动版本系统。是否有任何东西可以用来做这种事情,或者我需要自己写点什么吗?要明确:我没有使用PHP。

不太了解PHP,我不确定PHP的.htaccess等的Tomcat / JBoss类似物是什么。如果我必须编写自己的自动版本,我会从哪里开始?原理很清楚 - 使用文件的时间戳重写URL,但我不太了解使用JBoss / Tomcat进行URL重写。


更新

结合Pascalnovice建议的方法,以下是我的最终结果:

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变量,应用程序部署 时间戳:< / p>

// 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/\d{10}/(css|js|images)/(.*)$</from>
    <to>/static/$1/$2</to>
</rule>

非常感谢Pascalnovice的帮助。

3 个答案:

答案 0 :(得分:4)

以下解决方案更适合生产环境,因为您将增加每个版本的版本号。

<强>方法

  • 将产品版本号(版本号)附加到jsp文件中的js / css / images / static内容网址
  • 浏览器会使用包含版本号
  • 的网址缓存(js / css / static)文件
  • 当发布新版本时,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 files

    • 传入网址: /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或类似的构建工具
  • ,则可以自动更新版本

答案 1 :(得分:3)

如果您不想使用Apache HTTPD前置您的应用程序,那么您可以使用自定义servlet过滤器或重用现有的Url Rewrite Filter。此过滤器基于Apache的mod_rewrite并提供类似的功能。换句话说,它将允许实现与另一个答案中的PHP相同的解决方案。


  

之前我见过URL重写过滤器。你能详细说明我如何使用它吗?我真的不清楚如何将过滤器应用于这个问题,因为我不会完全调用包含在每个包含的JS / CSS文件中的JSP / JSTL函数,而且我不知道如何获取从WAR中的文件修改日期。

嗯,这个想法是模仿你所链接答案的“PHP解决方案”(让我们称之为选项1):

  1. 设置网址重写过滤器,将/css/my.123456.css中的任何请求重写为/css/my.css
  2. 实现一个Servlet,它将获得WAR内给定资源的File对象,并在返回该资源的路径中插入File#lastModified()
  3. 从JSP的CSS中调用Servlet

  4. 另一种方法(选项2)是将唯一的查询字符串附加到静态内容的URL,例如,服务器启动时间:

    1. 将服务器启动时间放在ServletContextListener的应用范围内(例如,在密钥"key"下)。
    2. 在JSP中

      <link rel="stylesheet" type="text/css" href="/css/my.css?${key.startupTime}">
      
    3. 亲:没有网址重写的东西了。 Con:不太理想(内容将在重启时请求)但可接受。


      在网上搜索有助于实现选项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的最佳选择。

答案 2 :(得分:1)

我们在网络应用中执行以下操作:

  1. 构建过程检索Subversion存储库编号并将其存储在Web应用程序的属性中。
  2. 构建过程还为WAR中的静态资产创建一个目录结构,其中包含此修订号:/ assets / 1234 / styles /...
  3. 过滤器/拦截器将资产路径(包括修订号)作为属性
  4. 放入所有请求中
  5. Jsp模板使用此资产路径属性为资产构建URLS