上代碼--原理是在response返回html的時候直接緩存html內容到redis中去html
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.CharArrayWriter; import java.io.PrintWriter; public class ResponseWrapper extends HttpServletResponseWrapper { private PrintWriter cachedWriter; private CharArrayWriter bufferedWriter; public ResponseWrapper(HttpServletResponse response) { super(response); // 這個是咱們保存返回結果的地方 bufferedWriter = new CharArrayWriter(); // 這個是包裝PrintWriter的,讓全部結果經過這個PrintWriter寫入到bufferedWriter中 cachedWriter = new PrintWriter(bufferedWriter); } @Override public PrintWriter getWriter() { return cachedWriter; } /** * 獲取原始的HTML頁面內容。 * * @return */ public String getResult() { return bufferedWriter.toString(); } }
import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.data.redis.core.StringRedisTemplate; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.concurrent.TimeUnit; public class RedisPageCacheFilter implements Filter { private static final Logger log = LoggerFactory.getLogger(RedisPageCacheFilter.class); private static ApplicationContext ctx; private final static String FILTER_URL_PATTERNS = "patterns"; private static String[] cacheURLs; private static int timeOut; @Override public void init(FilterConfig config) throws ServletException { String patterns = config.getInitParameter(FILTER_URL_PATTERNS); timeOut= Integer.parseInt(config.getInitParameter("expireTime")); cacheURLs = StringUtils.split(patterns, ","); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse resp = (HttpServletResponse) servletResponse; HttpServletRequest request = (HttpServletRequest) servletRequest; String url = request.getRequestURI(); boolean flag = false; if (cacheURLs != null && cacheURLs.length > 0) { for (String cacheURL : cacheURLs) { if (url.contains(cacheURL.trim())||url.matches(cacheURL)) { flag = true; break; } } } // 若是包含咱們要緩存的url 就緩存該頁面,不然執行正常的頁面轉向 if (flag) { String query = request.getQueryString(); if (query != null) { query = "?" + query; } final String key="REDISCACHE:"+url+query; log.info("當前請求緩存爲:" + url + query); // 訪問的是主頁 // 從緩存中獲得主頁html String html = getHtmlFromCache(key); if (null == html) { // 緩存中沒有 // 截取生成的html並放入緩存 log.info("緩存不存在,生成緩存"); ResponseWrapper wrapper = new ResponseWrapper(resp); // ***** 以上代碼在請求被處理以前執行 ***** filterChain.doFilter(servletRequest, wrapper); // ***** 如下代碼在請求被處理後前執行 ***** // 放入緩存 html = wrapper.getResult(); putIntoCache(key,html); } // 返回響應 resp.setContentType("text/html; charset=utf-8"); resp.getWriter().print(html); } else { filterChain.doFilter(servletRequest, resp); return; } } @Override public void destroy() { } private String getHtmlFromCache(String redisKey) { return RedisUtil.get(redisKey); } private void putIntoCache(String redisKey,String html) { RedisUtil.set(redisKey, html,timeOut*60); } }
使用方式:配置web.xmljava
<!-- 頁面緩存配置 redis cache--> <filter> <filter-name>redisCachingFilter</filter-name> <filter-class>xxxxx.xxxxx.xxxx.RedisPageCacheFilter</filter-class> <init-param> <param-name>suppressStackTrace</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>expireTime</param-name> <param-value>1</param-value> </init-param> <init-param> <param-name>patterns</param-name> <param-value>\/\d+.do,\/wap\/product\/list\/\d+.jhtm,\/wap\/product\/content\/\d+.action</param-value> </init-param> </filter> <filter-mapping> <filter-name>redisCachingFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> <filter-mapping> <filter-name>redisCachingFilter</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping>