|
|
由于效率的缘故,浏览器通常会缓存js文件,这就给我们带了一个问题:当服务器端部署的项目中的js文件进行了修改后,如果再客户端不手动去刷新一次页面,js的修改效果就不会起作用,因为浏览器还是用的缓存在本地的js文件。
为了解决这个问题,我们采用了这个方案,每当发布新的版本部署到服务器上的时候,我们给html页面中引用的js增加一个新的后缀,形如版本号的东西。
<script language="javascript" src="view/shell/login.js?version=20081112050245"></script>
为了自动完成这一功能,我们使用了ant,写了一个ant task来完成该项功能。
/** * 该任务遍历web目录,找出所有的模板文件,给js和css的引用加上版本号 * * @version 1.0 2008-07-02 * @author huangyuanmu * @since JDK 1.5.0_8 */public class AddJsAndCssVersionToVm extends Task {private String path;public void execute() throws BuildException {Date date = new Date();SimpleDateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");String version = df.format(date);addVersionToVm(path, version);}/** * 遍历web目录中的vm文件,给js和css的引用加上版本号 * * @author huangyuanmu 2008-07-02 * @param path */private void addVersionToVm(String path, String version) {File dir = new File(path);File[] files = dir.listFiles();if (files == null)return;for (int i = 0; i < files.length; i++) {if (files.isDirectory()) {addVersionToVm(files.getAbsolutePath(), version);} else {String strFileName = files.getAbsolutePath().toLowerCase();// 如果是符合条件的文件,则添加版本信息if (strFileName.endsWith(".vm")|| strFileName.endsWith(".html")|| strFileName.endsWith(".jsp")) {// RandomAccessFile raf = null;InputStream is = null;OutputStream os = null;List<String> contentList = new ArrayList<String>();// 读文件try {is = new FileInputStream(files);Reader r = new InputStreamReader(is);BufferedReader br = new BufferedReader(r);String line = null;while ((line = br.readLine()) != null) {String modLine = getModLine(line, version);if (modLine != null) {line = modLine;}line = line + "\r\n";contentList.add(line);}// 关闭流br.close();r.close();} catch (Exception e) {System.out.println("读文件失败");e.printStackTrace();} finally {if (null != is) {try {is.close();} catch (Exception e) {e.printStackTrace();}}}// 写文件try {os = new FileOutputStream(files);Writer w = new OutputStreamWriter(os);BufferedWriter bw = new BufferedWriter(w);for (Iterator<String> it = contentList.iterator(); it.hasNext();) {String line = it.next();bw.write(line);}// 更新到文件bw.flush();// 关闭流bw.close();w.close();} catch (Exception e) {System.out.println("写文件失败");e.printStackTrace();} finally {if (null != os) {try {os.close();} catch (Exception e) {e.printStackTrace();}}}}}}}/** * 查找行中是否有js或css的引用,如果有,则加上版本号 * * @author huangyuanmu 2008-07-03 * @param line */private String getModLine(String line, String version) {// 增加js版本line.trim();if (line.startsWith("<script") && line.endsWith("</script>")) {int pos = line.indexOf(".js");String modLine = line.substring(0, pos) + ".js?version="+ version + "\"></script>";return modLine;} else if (line.startsWith("<link")&& line.endsWith("rel=\"stylesheet\" type=\"text/css\">")) {int pos = line.indexOf(".css");String modLine = line.substring(0, pos) + ".css?version="+ version+ "\" rel=\"stylesheet\" type=\"text/css\">";return modLine;} else {return null;}}public void setPath(String path) {this.path = path;}}
当然,这个程序的实现还有一些缺点。首先,模板文件中对js和css的引用必须规范,符合程序代码中描述的格式。另外,不管文件内容有没有改变,都加上了新的版本号,这会用户访问时不必要的网络流量,可能会对页面展现的速度产生一些影响。
ant的build脚本文件在另外一篇中(http://huangyuanmu.iteye.com/admin/blogs/493144)。
|
|