使用 JBoss 对静态内容进行自动版本控制

发布于 2024-08-28 12:43:05 字数 2308 浏览 7 评论 0 原文

根据问答 这里,我想为在 JBoss 5 中运行的 Web 应用程序实现一个类似的自动版本控制系统。是否已经有任何东西可以做这类事情,或者我需要自己写一些东西?需要明确的是:我没有使用 PHP。

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


更新:

结合 Pascal 和 < a href="https://stackoverflow.com/questions/2630885/auto-versioning-of-static-content-with-jboss/3719518#3719518">新手,这就是我最终得到的结果:

1. 自定义 标签,这样我就不必看到 < code> 标签随处可见。

<%@ 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. 非常接近新手的步骤,但将 UrlRewriteFilter 映射到 web.xml 中的 /*

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

非常感谢 Pascal 新手寻求他们的帮助。

As per the Q&A here, I'd like to implement a similar auto-versioning system for a web app running in JBoss 5. Is there anything already out there to do this sort of thing, or will I need to write something myself? To be clear: I am not using PHP.

Not knowing much about PHP, I'm not sure what the Tomcat/JBoss analogs of PHP's .htaccess, etc. are. If I do have to write my own auto-versioning, where would I start? The principle is clear to me - rewriting the URL using the file's timestamp, but I don't know much about URL rewriting with JBoss/Tomcat.


Update:

Combining the approaches recommended by Pascal and novice, here's what I ended up with:

1. Custom <my:script/> and <my:style/> tags, so I wouldn't have to see <c:url/> tags everywhere.

<%@ 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. Following fairly closely to novice's steps, but mapping UrlRewriteFilter to /* in web.xml:

<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3. Injecting a CACHE_BUST variable to every new session (more or less...), an application deploy timestamp:

// On application deploy:
long CACHE_BUST = System.currentTimeMillis() / 1000;

// later...
session.setAttribute("cacheBust", CACHE_BUST);

4. ...so that I can use these rules in urlrewrite.xml:

<outbound-rule>
    <from>^/static/(css|js|images)/(.*)
lt;/from>
    <to>%{context-path}/static/%{session-attribute:cacheBust}/$1/$2</to>
</outbound-rule>

<rule>
    <from>^/static/\d{10}/(css|js|images)/(.*)
lt;/from>
    <to>/static/$1/$2</to>
</rule>

Many thanks to Pascal and novice for their help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

川水往事 2024-09-04 12:43:05

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

方法:

  • 将产品版本号(版本号)附加到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,例如,

    <前><代码><过滤器>
    <过滤器名称>urlRewriteFilter
    <过滤器类>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter

    <过滤器映射>
    <过滤器名称>urlRewriteFilter
    /v/*

  • 更新 jsp 文件中的“abc.js”,例如,

    <代码>
        <头>
            <脚本类型=“text/javascript”src=“”>
        
    
    
  • 写入urlrewritefilter.xml,例如,

    <出站规则>
        <来自>^/v/(css|js|static)/(.*)$
        <到>%{context-path}/v/updateVersionNumberHere/$1/$2
    
    
    <规则>
        <来自>^/v/updateVersionNumberHere/(css|js|static|images)/(.*)$
        <至>/$1/$2
    
    

    说明:

    当jsp提供给客户端时

    • jsp中提到的url: /v/js/abc.js
    • 应用出站规则后: /contextPath/v/3.4.5/js/abc.js

    当浏览器调用js/css/静态文件时

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

Following solution is better suited in production environment as you would be incrementing the version number for each release.

Approach:

  • append the product release number(version number) to the js/css/images/static content urls in jsp files
  • browser would cache (js/css/static)files with the url containing the version number
  • when a new version is released, the jsp files will have the urls of js/css/static files with new version number, so the browser will make a call as it can't find the content for the new url

Steps:

  • include urlrewritefilter.jar in the class path (get it from http://www.tuckey.org/urlrewrite/)
  • update web.xml with the url pattern, for e.g,

    <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>
    
  • update 'abc.js' in the jsp file, for e.g.,

    <html>
        <head>
            <script type="text/javascript" src="<c:url value="/v/js/abc.js"/>"></script>
        </head>
    </html>
    
  • write urlrewritefilter.xml, for e.g.,

    <outbound-rule>
        <from>^/v/(css|js|static)/(.*)
    lt;/from>
        <to>%{context-path}/v/updateVersionNumberHere/$1/$2</to>
    </outbound-rule>
    
    <rule>
        <from>^/v/updateVersionNumberHere/(css|js|static|images)/(.*)
    lt;/from>
        <to>/$1/$2</to>
    </rule>
    

    Explanation:

    when jsp is served to client

    • url mentioned in the jsp: /v/js/abc.js
    • after applying outbound rule: /contextPath/v/3.4.5/js/abc.js

    when browser makes a call for js/css/static files

    • incoming url: /contextPath/v/3.4.5/js/abc.js
    • after applying rule: /js/abc.js

Points:

  • browser would catch the js files with url /contextPath/v/3.4.5/js/abc.js, next you deploy a new version of jsp files they might have the url /contextPath/v/4.5.6/js/abc.js, so the browser would make a call for js file instead of using the cached js file.
  • version updating could be automated if you use maven or similar build tool
娇纵 2024-09-04 12:43:05

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


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

好吧,这个想法是完全模仿您链接到的答案的“PHP 解决方案”(让我们将此选项称为 1):

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

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

  1. 将服务器启动时间从 ServletContextListener (比如在键 "key" 下) )。
  2. 在你的 JSP 中

    
    

Pro 中:不再需要 url 重写。缺点:不太理想(重新启动时将请求内容)但可以接受。


在网上搜索一些有助于实现选项 1 的步骤 #2 的代码时,我发现了 Spring 的 oswsResourceServlet 正在做类似的事情,你可以看看它的源代码。但是,在更仔细地阅读其 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 的依赖关系不是问题的话,这在我看来是最好的选择。

If you don't want to front your application with Apache HTTPD, then you could use a custom servlet filter or reuse the existing Url Rewrite Filter. This filter is based on Apache's mod_rewrite and offers similar capabilities. In other words, it would allow to implement the same solution than the PHP one of the other answer.


I've seen the URL rewrite filter before. Could you elaborate on how I'd use that? I'm really not clear on how I'd apply a filter to this problem, since I wouldn't exactly be calling a JSP/JSTL function wrapped around each included JS/CSS file, and I have no idea about how to get the date modified from a file that's in a WAR.

Well, the idea was to mimic exactly the "PHP solution" of the answer you linked to (let's call this option 1):

  1. Setup the Url Rewrite Filter to rewrite any request to say /css/my.123456.css into /css/my.css
  2. Implement a Servlet that would get a File object for a given resource inside the WAR and insert File#lastModified() in the returned path to that resource.
  3. Invoke that Servlet from the JSP for the CSS.

Another approach (option 2) would be to append an unique query string to the URL of the static content, e.g. the server startup time:

  1. Put the server startup time in the application scope from a ServletContextListener (say under the key "key").
  2. In you JSP

    <link rel="stylesheet" type="text/css" href="/css/my.css?${key.startupTime}">
    

Pro: no url rewrite stuff anymore. Con: Less optimal (content will be request on restart) but acceptable.


While searching the web for some code that could help to implement the step #2 of option 1, I found Spring's o.s.w.s.ResourceServlet that is doing something similar, you could look at its source code. But, while reading its javadoc more carefully, I realized that this servlet is actually exactly what you're looking for. Map it like this:

<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>

And set its applyLastModified property to true. My understanding of the javadoc is that it should do the trick. This is option 3 and this is IMO the best option if adding a dependency on this servlet in not an issue.

黑寡妇 2024-09-04 12:43:05

我们在 Web 应用程序中执行以下操作:

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

We do the following in our web app:

  1. Build process retrieves Subversion repository number and stores it in a property within the web application.
  2. Build process also creates a directory structure for static assets within the WAR that incorporates this revision number: /assets/1234/styles/...
  3. Filter/interceptor puts assets path (including revision number) into all requests as attribute
  4. Jsp templates use this assets path attribute to construct URLS for assets
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文