解决jsp文件的缓存问题

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、总结

  使用这种方法有个弊端,每次发布时会造成很多文件被修改,对于这种修改,建议不上传,打包后可恢复原代码,

  仅供参考,如有错误请联系我

原文地址:https://www.cnblogs.com/niusj/p/11662592.html