版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Qizonghui/article/details/80947451
缓存机制在页面性能优化中是非常重要的,缓存可以使页面尽可能快加载,具有减轻带宽,降低服务负荷,提高用户体验等;我们说了这么多缓存好处,为什么现在要说清缓存机制;因为在一个项目在开发中不稳定,频繁发布过程中我们就会发现缓存不是那么好,因为缓存的存在经常会使我们发布的功能不能实现,用户体验非常差;所以在开发阶段,频繁上线发布阶段我们清楚缓存还是有必要的;
缓存清除一版有:每个页面加http头部,加载每个页面加版本号,使用打包的方式加载版本号相当于每次打包发布的项目页面都是不同的页面;
1.给页面加头部:
<HEAD>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</HEAD>
http头部信息:"Expires"和"Cache-Control"为应用程序服务器提供了一个控制浏览器和代理服务器上缓存机制 。http头信息Expires告诉代理服务器缓存页面过期时间。http1.1规范中新定义的头部信息Cache-Control可以通知浏览器不缓存任何页面,每次浏览器重新访问服务器获取页面;
no-cache:强制缓存从服务器上获取新页面
no-store:在任何环境下缓存不保存任何页面
2.给每个url加参数:
在需要打开的url后面增加一个随机数:random():这样每次请求url后面参数不一样,相当于请求的是不同多的页面,用这种方式也是可以达到我们的要求:只要为了达到目标不择手段吗;
我们主要是看看怎么通过java代码来控制缓存;毕竟上面两种方式还是有缺陷的,每个页面加载,这样在我们后面项目稳定后如果还是使用的话,就会影响程序给用户带来的体验了;
1.使用filter加载http头:
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
//response对象
HttpServletResponse res = (HttpServletResponse) response;
// 设定网页的到期时间,一旦过期则必须到服务器上重新调用
res.setDateHeader("Expires", -1);
// Cache-Control 指定请求和响应应遵循的缓存机制 no-cache指示请求或响应消息是不能缓存的
res.setHeader("Cache-Control", "no-cache");
// 用于设定禁止浏览器从本地缓存中调用页面内容,设定后一旦离开页面就无法从Cache中再调出
res.setHeader("Pragma", "no-cache");
// 放行
chain.doFilter(request, res);
}
2.是使用filter给url加参数;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EmsCacheCleanFilter implements Filter {
private static Logger log = LoggerFactory
.getLogger(EmsCacheCleanFilter.class);
private static final String STATIC_TAIL = "__xxxx_t=";
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
// 1.获取request请求的url访问路径
String reqeustURL = req.getRequestURL().toString();
String queryStr = req.getQueryString();
// 2.通过给静态资源添加时间戳,去避免缓存问题
// 当访问的静态资源是以*.js,*.css,*.html结尾时才给其加上时间戳
if (reqeustURL != null) {
if (checkURL(reqeustURL)) {
String newURL = null;
// 日期类型时间戳
// String date = DateUtil.date2String(new Date(), "yyyyMMdd");
// 毫秒值风格时间戳
String date = new Date().getTime() + "";
// 如果?后面有参数
if (StringUtils.isNotBlank(queryStr)
&& queryStr.trim().indexOf(STATIC_TAIL) == -1) {
newURL = reqeustURL + "?" + queryStr + "&" + STATIC_TAIL
+ date;
newURL = newURL.replaceAll("\\n\\r", "");
resp.setHeader("content-type",
"text/application;charset=UTF-8");
resp.sendRedirect(newURL);
}
// 如果?后面没有参数
if (StringUtils.isBlank(queryStr)) {
newURL = reqeustURL + "?" + STATIC_TAIL + date;
newURL = newURL.replaceAll("\\n\\r", "");
resp.setHeader("content-type",
"text/application;charset=UTF-8");
resp.sendRedirect(newURL);
}
}
try {
// 只要请求url不为空放行
chain.doFilter(request, response);
} catch (Exception e) {
e.printStackTrace();
log.info("[http请求出现异常,检查网络是否正常,或者再尝试一次![exception:]"
+ e);
}
}
}
/**
* @description:判断url中是否包含这些后缀名
* @param url
* 访问的url路径
* @return
*/
public Boolean checkURL(String url) {
String[] checks = { ".js", ".css", ".jsp",".html" };
for (int i = 0; i < checks.length; i++) {
if (url.endsWith(checks[i])) {
return true;
}
}
return false;
}
/**
* @description:解决302问题未解决)
* @param
* @param response
*/
public void fixResponse(HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-type", "text/application;charset=UTF-8");
response.setStatus(200);
try {
PrintWriter out = response.getWriter();
out.write("<html lang='zh-CN'>"
+ "<head><meta http-equiv='content-type' content='text/html;charset=UTF-8'/></head></html>");
} catch (IOException e) {
e.printStackTrace();
log.info("[浏览器或系统出现异常,请重新访问]-[zengwei]");
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
public void destroy() {
}
}
配置filter生效:web.xml
<filter>
<filter-name>emsCacheCleanFilter</filter-name>
<filter-class>com.telegnosis.iframework.filter.EmsCacheCleanFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>emsCacheCleanFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这些都是在加载的时候处理缓存;下一篇我们将通过打包的方式来处理缓存,就是每次打包都给页面加载一个(版本号),这样就是每次打包的静态资源都是不一样的;所以可以起到清楚缓存的效果;