1、背景说明
项目是比较传统的SSM项目,页面是jsp文件,前端的逻辑js代码包括css文件单独拿出去了,
在jsp中设置禁用缓存是不明智的,首先缓存是有必要的,只有当文件变化时,才应该重新拉取最新的文件
再者,即便在jsp中禁用了缓存,那他外联的资源文件依然会有缓存
2、解决办法
为了最大限度的使用缓存,同时避免客户端的无效缓存,我编写了一个工具类,再每次发布时,执行该工具类
该工具主要是计算资源的文件名,大小、最后更新时间,生成hash,加载文件的访问链接参数上。代码如下:
1 package com.autobio.site;
2
3 import com.autobio.site.common.utils.FileUtils;
4 import org.springframework.util.DigestUtils;
5 import java.io.File;
6 import java.io.IOException;
7 import java.util.List;
8
9 /**
10 * @author niushijie
11 * @datetime 2019-07-12 10:49
12 * @function 静态资源更新hash标识
13 **/
14 public class RefreshAssetsHash {
15 public static void main(String[] args) throws IOException {
16 System.out.println("开始更新jsp文件的hash值-->");
17 System.out.println("被更新的文件如下: ");
18 File file = new File("source/src/main/webapp/WEB-INF/views/modules");
19 updateFileHash(file);
20 System.out.println("<--结束更新jsp文件的hash值");
21 }
22
23 private static void updateFileHash(File file) throws IOException {
24 if (file.isDirectory()) {
25 File[] files = file.listFiles();
26 File headJsp = new File("source/src/main/webapp/WEB-INF/views/include/head.jsp");
27
28 for (File f : files) {
29 if (f.isDirectory()){
30 updateFileHash(f);
31 }else{
32 calc(f);
33 }
34 }
35 calc(headJsp);
36 }
37
38 }
39
40 private static void calc(File f) throws IOException {
41 List<String> lines = FileUtils.readLines(f);
42 boolean isUpdated = false;
43 for (int i=0;i<lines.size();i++) {
44 String line = lines.get(i);
45 // 只更新head部分
46 if (line.contains("</head>")){
47 break;
48 }
49 if (line.contains("${assets}")&&(line.contains("href")||line.contains("src"))){
50 String temp = line.substring(line.lastIndexOf("}")+1);
51 // jsp文件中的完整路径
52 String path = temp.substring(0, temp.indexOf("\""));
53 // 原始Hash值
54 String oldHash = null;
55 // 文件的路径(去除Hash的结果)
56 String filePath = path;
57 if (path.contains("?")){
58 oldHash = path.substring(path.indexOf("?")+1);
59 filePath = path.substring(0, path.indexOf("?"));
60 }
61 // 取到文件
62 File target = new File("source/src/main/webapp/assets/"+filePath);
63 // 计算hash的元素
64 String params = target.getName()+ target.length() + target.lastModified();
65 String hashValue = DigestUtils.md5DigestAsHex(params.getBytes());
66 // 比较新旧hash
67 if (oldHash == null || !oldHash.equals(hashValue)){
68 line = line.replace(path, filePath + "?"+hashValue);
69 // 赋值新行
70 lines.set(i, line);
71 isUpdated = true;
72 }
73 }
74 }
75 if (isUpdated){
76 // 更新文件
77 FileUtils.writeLines(f, lines);
78 System.out.println(f.getAbsolutePath());
79 }
80 }
81 }3、总结
使用这种方法有个弊端,每次发布时会造成很多文件被修改,对于这种修改,建议不上传,打包后可恢复原代码,
仅供参考,如有错误请联系我
















