学习笔记:Maven构造版本号的方法解决浏览器缓存问题
需要解决的问题
在做WEB系统开发时,为了提高性能会利用浏览器的缓存功能,其实即使不显式的申明缓存,现代的浏览器都会对静态文件(js、css、图片之类)缓存。但也正因为这个问题导致一个问题,就是资源的缓存逻辑有时出现问题后服务器的最新版本文件无法更新客户端的缓存。
这个问题会给用户产生许多的困扰,当然首先是测试人员会很头痛,一些看起来没有修复的bug为什么开发要说做好了?这种时候我会无奈的说:ctrl+f5刷新一下。但这毕竟不是解决问题的方法。
思路与方法考虑
思路
之前没有着手处理过这样的问题,只是知道缓存可以通过时间戳、版本戳的方式来解决。说白了就是让link的url不一样浏览器自然会下载最新版本,想想这不是挺容易的事情嘛。项目紧也就没当回事,等有时间了再来解决这个问题。
好了,最近有时间了开始解决。找了许多的方法,发现这确实是简单的加一个版本号/时间戳就能解决:
<link rel="stylesheet" type="text/css" href="/css/common.css?ver=${sysVersion}" />
上面代码中在资源后面加了一个?ver=${sysVersion}
注:项目中使用的是velocity,所以${sysVersion}是指velocity中的变量。
新的问题
但一个新问题产生,我们是使用hudsun+maven来进行构造并自动发布及部署到web服务器上。那么我们如何在maven构造时打上一个版本戳呢?
方法
- 通过某种方法生成一个版本号写入到文件,系统启动时加载此版本号,这样velocity就能够使用这个版本号从而解决缓存更新的问题。这种就是单一的统一版本号方法。
- 通过前端的编译工具,grunt、F.I.S这类工具来完成,特别是F.I.S可以实现md5戳的模式,直接针对单个资源进行版本更新,这样就比较精确也最大化了缓存的作用。
最后还是选择了第一种方法,因为集成前端编译工具的方法我没有搞定T_T,原因:
1、F.I.S需要基于Node.js,这个又要配置许多东西,有点麻烦,当我自己搭建环境就反复了许多天,后来发现是网络墙原因。
2、另外由于项目做的不是很规范,所以F.I.S生成时需要改动比较多的代码,这个是我这种懒人不太愿意做的
于是先用简单的方法解决之,最后经过1天的配置也确实完成了。
采用最简单的单一版本号
单一的版本号一下子就简化了解决问题的难度,只要想办法在发布时生成一个版本号即可,那就不管是时间、数字或者其他什么,所有的资源都引用此版本号即可。找到了一个maven的插件:maven-svn-revision-number-plugin,这个插件可以获取svn的版本号用作build号,这样的好处就是只要有代码提交就会有新版本产生。插件的代码如下:
<plugin>
<groupId>com.google.code.maven-svn-revision-number-plugin</groupId>
<artifactId>maven-svn-revision-number-plugin</artifactId>
<version>1.7</version>
<configuration>
<verbose>true</verbose>
<entries>
<entry>
<prefix>prefix</prefix><!-- 版本戳的前缀-->
<depth>empty</depth>
</entry>
</entries>
</configuration>
<executions>
<execution>
<phase>validate</phase><!-- 生命周期阶段-->
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.tmatesoft.svnkit</groupId><!-- 由于使用的是svn1.8版本,所以需要依赖这个插件-->
<artifactId>svnkit</artifactId>
<version>1.8.9</version>
</dependency>
</dependencies>
</plugin>
这个插件的作用是在maven构造时获取最新的svn版本号,然后利用maven的resources的filtering来在各个配置文件中作用变量使用。这样就实现了构造时将版本号写入文件。
resources的代码:
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**.properties</include><!-- 只对properties文件进行处理-->
</includes>
<filtering>true</filtering><!-- 表示开启变量嵌入 -->
</resource>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**.properties</exclude>
</excludes>
<filtering>false</filtering>
</resource>
</resources>
因为使用properties文件作为载体,所以上述的设置目的就是找到properties文件然后写入版本号,我建了一个build_version.properties文件,里面写了一个设置项:
build.version=${prefix.committedRevision}
${prefix.committedRevision}就可以获取maven-svn-revision-number-plugin插件生成的版本号。
这样设置好了后,使用Maven install就可以看到效果了,构造后在target目录找到build_version.properties文件查看内容:
build.version=114912
此时就变成了一个数字。
在此看一看maven-svn-revision-number-plugin插件中会产生哪些变量:
[INFO] --- maven-svn-revision-number-plugin:1.7:revision (default) @ zrtc ---
[INFO] inspecting E:\workspace\web
[INFO] prefix = prefix
[INFO] depth = empty
[INFO] report unversioned = true
[INFO] report ignored = false
[INFO] report out-of-date = false
[INFO] collecting status information
[INFO] 114969 114912 E:\workspace\web
[INFO] setting properties
[INFO] prefix.repository =
[INFO] prefix.path =
[INFO] prefix.revision = 114969
[INFO] prefix.mixedRevisions = false
[INFO] prefix.committedRevision = 114912
[INFO] prefix.committedDate = 2015-10-23 09:03:39 +0800 (Fri, 23 Oct 2015)
[INFO] prefix.status =
[INFO] prefix.specialStatus =
可以看到插件有几个变量,其中我使用了committedRevision,这个就是项目svn目录最后一次提交的版本。revision 则是svn最新的版本号。在其他文件使用时需要加上prefix.这个前缀,这是在配置文件中定义过的,可以看上面的配置内容。
<prefix>prefix</prefix><!-- 版本戳的前缀-->
这个前缀自己取名就可以了。
自此功能完成,解决了资源版本更新的问题。看看浏览器前端页面源代码:
<link rel="stylesheet" href="/css/h_login.css?ver=114912" type="text/css">
未来的目标
最近因为解决前端客户端资源更新的问题也看到了一些更好的方法,比如F.I.S这种前端工程构建工具。在了解的过程中知道了一个前端工程化的概念,有些大,但确实是未来的一种发展趋势。在B/S开发越来越深入的阶段,浏览器+服务器的这种开发平台已经证明了其优越性,移动互联网、云计算都已经体现了这种发展趋势。而浏览器是最近10年人们用的最多的软件了吧?而且浏览器已经证明了其无所不能,基于HTML+CSS就可以实现无数美秒的界面,原先常见的商业系统都也搬到了B/S架构下。可见HTML是多么牛逼的开发平台。
站在这个时代如果还不能做点和时代相关的事情是不是感觉有点过时?所以在未来要思考一下前端系统的模块化,最终实现工程化。
学习笔记:Maven构造版本号的方法解决浏览器缓存问题的更多相关文章
- 前端学习笔记汇总(之merge方法)
学习笔记 关于Jquery的merge方法 话不多说,先上图 使用jquery时,其智能提示如上,大概意思就是合并first和second两个数组,得到的结果是first+(second去重后的结果) ...
- 《深入Java虚拟机学习笔记》- 第19章 方法的调用与返回
<深入Java虚拟机学习笔记>- 第19章 方法的调用与返回
- Go学习笔记07-结构体与方法
Go学习笔记07-结构体与方法 Go语言 面向对象 结构的定义与创建 面向对象 Go语言只支持封装,不支持继承和多态. Go语言中只有struct,即结构体:没有class. 结构的定义与创建 pac ...
- Java程序猿的JavaScript学习笔记(9—— jQuery工具方法)
计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...
- js 给url添加时间戳 解决浏览器缓存
//解决浏览器缓存 function timestamp(url){ // var getTimestamp=Math.random(); var getTimestamp=new Dat ...
- js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();)
js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();) ...
- 给url添加时间戳,解决浏览器缓存
//解决浏览器缓存function timestamp(url){ // var getTimestamp=Math.random(); var getTimestamp=new Date().get ...
- [原创]java WEB学习笔记34:Session 案例 之 解决表单重复提交
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- 学习笔记——Maven实战(三)多模块项目的POM重构
重复,还是重复 程序员应该有狗一般的嗅觉,要能嗅到重复这一最常见的坏味道,不管重复披着怎样的外衣,一旦发现,都应该毫不留情地彻底地将其干掉.不要因为POM不是产品代码而纵容重复在这里发酵,例如这样一段 ...
随机推荐
- ASP.NET Core 之 Identity 入门(二)
前言 在 上篇文章 中讲了关于 Identity 需要了解的单词以及相对应的几个知识点,并且知道了Identity处在整个登入流程中的位置,本篇主要是在 .NET 整个认证系统中比较重要的一个环节,就 ...
- ASP.NET Aries 入门开发教程2:配置出一个简单的列表页面
前言: 朋友们都期待我稳定地工作,但创业公司若要躺下,也非意念可控. 若人生注定了风雨飘摇,那就雨中前行了. 最机开始看聊新的工作机会,欢迎推荐,创业公司也可! 同时,趁着自由时间,抓紧把这系列教程给 ...
- C#高性能TCP服务的多种实现方式
哎~~ 想想大部分园友应该对 "高性能" 字样更感兴趣,为了吸引眼球所以标题中一定要突出,其实我更喜欢的标题是<猴赛雷,C#编写TCP服务的花样姿势!>. 本篇文章的主 ...
- .Net Core MVC 网站开发(Ninesky) 2.2、栏目管理功能-System区域添加
在asp或asp.net中为了方便网站的结构清晰,通常把具有类似功能的页面放到一个文件夹中,用户管理功能都放在Admin文件夹下,用户功能都放在Member文件夹下,在MVC中,通常使用区域(Area ...
- Android 剪贴板详解
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Clipboard 如本文有助于你理解 Android 剪贴板,不妨给我一个 Star.对于码农而言, ...
- 用C语言封装OC对象(耐心阅读,非常重要)
用C语言封装OC对象(耐心阅读,非常重要) 本文的主要内容来自这里 前言 做iOS开发的朋友,对OC肯定非常了解,那么大家有没有想过OC中NSInteger,NSObject,NSString这些对象 ...
- go语言:多个[]byte数组合并成一个[]byte
场景:在开发中,要将多个[]byte数组合并成一个[]byte,初步实现思路如下: 1.获取多个[]byte长度 2.构造一个二维码数组 3.循环将[]byte拷贝到二维数组中 package gst ...
- Java多态性——分派
一.基本概念 Java是一门面向对象的程序设计语言,因为Java具备面向对象的三个基本特征:封装.继承和多态.这三个特征并不是各自独立的,从一定角度上看,封装和继承几乎都是为多态而准备的.多态性主要体 ...
- 使用EF CodeFirst 创建数据库
EntityFramework 在VS2015添加新建项时,选择数据->ADO.NET 实体数据模型,有一下选项 来自数据库的EF设计器,这个就是我们最常用的EntityFramework设计模 ...
- IteratorPattern(迭代子模式)
/** * 迭代子模式 * @author TMAC-J * 聚合:某一类对象的集合 * 迭代:行为方式,用来处理聚合 * 是一种行为模式,用于将聚合本身和操作聚合的行为分离 * Java中的COLL ...