【问题标题】:Manage aggressive caching using URL fingerprinting in a Java/Maven way以 Java/Maven 方式使用 URL 指纹管理积极缓存
【发布时间】:2013-03-06 21:09:31
【问题描述】:

我正在尝试找到管理浏览器缓存以在 Java/Maven 项目中重新加载修改后的 JavaScript/CSS 资源的最佳解决方案。 最普遍的解决方案似乎是 Maven 过滤以在构建时向资源 URL 添加时间戳。例如:

<script type="text/javascript" src="resource.js?v=${maven.build.timestamp}"></script>

但最有效的方法是添加文件的校验和/哈希(又名指纹)而不是构建日期,这样资源就不会在每次部署后重新加载,而是仅在必要时重新加载。 我正在拼命寻找这个模型的正确/通用实现,使用 Java 或 Maven 插件。

有什么想法吗?

谢谢。

【问题讨论】:

    标签: java maven maven-plugin browser-cache fingerprinting


    【解决方案1】:

    您确实想使用指纹与查询参数。查询参数方法并不总是有效,大多数代理不会缓存它。更改 URL 或实际文件名效果更好。

    这就是我在 Maven、Git、Tomcat、Dojo 项目中处理这个问题的方式。我使用http://mojo.codehaus.org/buildnumber-maven-plugin/ 来获取我的Git rev。然后在构建我的 WAR 时使用过滤将值注入我的 JSP。

    pom.xml

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>buildnumber-maven-plugin</artifactId>
            <version>1.1</version>
            <executions>
                <execution>
                    <phase>validate</phase>
                    <goals>
                        <goal>create</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <doCheck>false</doCheck>
                <doUpdate>false</doUpdate>
                <shortRevisionLength>8</shortRevisionLength>
                <revisionOnScmFailure></revisionOnScmFailure>
            </configuration>
        </plugin>
    
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <warName>${project.name}-${project.version}-${buildNumber}</warName>
                <webResources>
                    <resource>
                        <directory>src/main/webapp/WEB-INF/views/includes</directory>
                        <targetPath>WEB-INF/views/includes</targetPath>
                        <filtering>true</filtering>
                    </resource>
                </webResources>                  
                ......
            </configuration>
        </plugin>
    

    在我的主要 JSP 中包含我有

    <script src="${pageContext.request.contextPath}/${buildNumber}/static/js/ckeditor/ckeditor.js"></script>
    <script src="${pageContext.request.contextPath}/${buildNumber}/static/js/build/dojo/dojo.js"  data-dojo-config="parseOnLoad: true"></script>
    

    要进行重写,我使用http://tuckey.org/urlrewrite/。我只有一个简单的规则。

    我的第一个过滤器条目 web.xml

    <filter>
        <filter-name>UrlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
        <init-param>
            <param-name>logLevel</param-name>
            <param-value>WARN</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    

    urlrewrite.xml

    <rule match-type="regex">
        <from>^/[0-9A-Za-z_.\-]+/static/(.*)$</from>
        <to>/static/$1</to>
    </rule>
    

    【讨论】:

    • 感谢您提供有用的 URL 重写部分。但是内部版本号的行为与 ${maven.build.timestamp} 几乎相同。您的资产将在每个新版本之后重新下载,即使它们没有更改。
    • 也许我想念你的问题。您是否只想强制在部署之间更改的文件?
    • 我将我所有的 js 代码编译并压缩成几个文件。所以我真的不需要担心哪些文件有变化。用户只需在每次更新时下载 js 文件。
    【解决方案2】:

    我还没有使用它,但maven-fingerprint-plugin 看起来不错。

    它只需要一点 maven 配置,然后它会自动将文件中的所有 url 重建为指定版本。

    无需在资源 URL 中手动保留 ${buildNumber}${hashVersion} 或其他指纹选项。

    来自存储库:

    <pluginRepositories>
        <pluginRepository>
            <id>fprint-repo</id>
            <url>https://raw.github.com/dernasherbrezon/maven-fingerprint-plugin/master/maven-fingerprint-plugin/mvn-repo</url>
        </pluginRepository>
    </pluginRepositories>
    

    然后

    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <excludeResources>
            <excludeResource>://</excludeResource>
            <excludeResource>//</excludeResource>
        </excludeResources>
        <!-- ${basedir}/src/main/webapp by default -->
        <sourceDirectory>${basedir}/target/webcombined</sourceDirectory>
        <!-- ${project.build.directory}/fingered-web by default -->
        <outputDirectory>${basedir}/target/fingered</outputDirectory>
        <!-- Remove unnecessary spaces between tags. Make single line page.
        Takes into consideration <pre> tags -->
        <trimTagExtensions>
            <trimTagExtension>html</trimTagExtension>
        </trimTagExtensions>
        <extensionsToFilter>
            <extensionToFilter>html</extensionToFilter>
            <extensionToFilter>jsp</extensionToFilter>
            <extensionToFilter>tag</extensionToFilter>
            <extensionToFilter>css</extensionToFilter>
            <extensionToFilter>js</extensionToFilter>
        </extensionsToFilter>
        <!-- cdn host. Not required. For example using
        "//accountname.r.worldssl.net": /css/bootstrap.css =>
        //accountname.r.worldssl.net/css/<md5>bootstrap.css -->
        <cdn>${cdn}</cdn>
    </configuration>
    

    就是这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      • 2021-07-28
      相关资源
      最近更新 更多