日常使用hml都知道,浏览器加载完页面后,页面不做任何缓存机制的处理话,会将静态数据缓存,下次打开速度就快很多,但平时涉及页面关联的js服务升级后,有可能关联的内容还是旧版本的,这个时候需要手动清除缓存。
换另一种思路,我们在页面生成的时候,关联的css,js等资源文件加上一个版本号,则下次升级重启后,页面就会重新渲染新的版本信息,如下
<script src="~/jquery/jquery.cookie.js?v=20210817"></script>
<script src="~/js/base.js?v=20210817"></script>
解决思路
在后台通过过滤器,只过滤 html的资源文件,通过获取文件内容,替换以 css,js结尾的内容,对应的加上版本信息,参考代码如下:
import org.springframework.stereotype.Service;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 浏览器缓存更新机制,服务每次重启都会动态生成一个版本号
*
*/
@Service
public class HttpCacheFilter extends GenericFilterBean {
private String version = "";
protected void initFilterBean() throws ServletException {
String path = HttpCacheFilter.class.getClassLoader().getResource("").getPath();
if(path.indexOf("jar!/BOOT-INF/") > 0){//jar包运行环境
path = path.split("!/BOOT-INF/")[0];
path = path.substring(path.indexOf("/") + 1);
File file = new File(path);
long modifytime = file.lastModified();
Date modifydate = new Date(modifytime);
SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
version = sdf.format(modifydate);
}else{//开发环境直接使用当前时间
SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
version = sdf.format(new Date());
}
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
//通过版本号控制 start
String HTTP_CACHE_ENABLE = SysConfig.getProperty("CACHE_ENABLE_CACHE_REPLACE", "1");
if("1".equals(HTTP_CACHE_ENABLE)){
ResponseWrapper wrapperResponse = new ResponseWrapper(res);//转换成代理类
chain.doFilter(request, wrapperResponse);
try{
String contentType = wrapperResponse.getContentType();
if(contentType != null && contentType.indexOf("html") > -1){
String content = wrapperResponse.getContent();//获取返回值
if(content != null){
content = content.replace(".js"", ".js?v="+version+""");
content = content.replace(".css"", ".css?v="+version+""");
byte outByte[] = content.getBytes(wrapperResponse.getCharacterEncoding());
wrapperResponse.setContentLength(outByte.length);
ServletOutputStream out = response.getOutputStream();
out.write(outByte);
out.flush();
}
}else{
ServletOutputStream out = response.getOutputStream();
out.write(wrapperResponse.getOriginalBuffer().toByteArray());
out.flush();
}
}catch(Exception e){
e.printStackTrace();
}
}else{
chain.doFilter(request, res);
}
//通过版本号控制 end
}
}