java-redis缓存jsp页面

上代码 -- 原理是在 response 返回 html 的时候直接缓存 html 内容到 redis 中去

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;

</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> ResponseWrapper(HttpServletResponse response) {
    </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">(response);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 这个是我们保存返回结果的地方</span>
    bufferedWriter = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> CharArrayWriter();
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 这个是包装PrintWriter的,让所有结果通过这个PrintWriter写入到bufferedWriter中</span>
    cachedWriter = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> PrintWriter(bufferedWriter);
}

@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> PrintWriter getWriter() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cachedWriter;
}

</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * 获取原始的HTML页面内容。
 *
 * </span><span style="color: rgba(128, 128, 128, 1)">@return</span>
 <span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getResult() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> 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);

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> ApplicationContext ctx;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String FILTER_URL_PATTERNS = "patterns"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> String[] cacheURLs;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> timeOut;

@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> init(FilterConfig config) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> ServletException {
    String patterns </span>=<span style="color: rgba(0, 0, 0, 1)"> config.getInitParameter(FILTER_URL_PATTERNS);
    timeOut</span>= Integer.parseInt(config.getInitParameter("expireTime"<span style="color: rgba(0, 0, 0, 1)">));
    cacheURLs </span>= StringUtils.split(patterns, ","<span style="color: rgba(0, 0, 0, 1)">);
}

@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> IOException, ServletException {
    HttpServletResponse resp </span>=<span style="color: rgba(0, 0, 0, 1)"> (HttpServletResponse) servletResponse;
    HttpServletRequest request </span>=<span style="color: rgba(0, 0, 0, 1)"> (HttpServletRequest) servletRequest;

    String url </span>=<span style="color: rgba(0, 0, 0, 1)"> request.getRequestURI();
    </span><span style="color: rgba(0, 0, 255, 1)">boolean</span> flag = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (cacheURLs != <span style="color: rgba(0, 0, 255, 1)">null</span> &amp;&amp; cacheURLs.length &gt; 0<span style="color: rgba(0, 0, 0, 1)">) {
        </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (String cacheURL : cacheURLs) {
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (url.contains(cacheURL.trim())||<span style="color: rgba(0, 0, 0, 1)">url.matches(cacheURL)) {
                flag </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
                </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
            }
        }
    }

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果包含我们要缓存的url 就缓存该页面,否则执行正常的页面转向</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (flag) {
        String query </span>=<span style="color: rgba(0, 0, 0, 1)"> request.getQueryString();
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (query != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
            query </span>= "?" +<span style="color: rgba(0, 0, 0, 1)"> query;
        }

        </span><span style="color: rgba(0, 0, 255, 1)">final</span> String key="REDISCACHE:"+url+<span style="color: rgba(0, 0, 0, 1)">query;
        log.info(</span>"当前请求缓存为:" + url +<span style="color: rgba(0, 0, 0, 1)"> query);

        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 访问的是主页
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 从缓存中得到主页html</span>
        String html =<span style="color: rgba(0, 0, 0, 1)"> getHtmlFromCache(key);
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">null</span> ==<span style="color: rgba(0, 0, 0, 1)"> html) {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 缓存中没有
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 截取生成的html并放入缓存</span>
            log.info("缓存不存在,生成缓存"<span style="color: rgba(0, 0, 0, 1)">);
            ResponseWrapper wrapper </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ResponseWrapper(resp);
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ***** 以上代码在请求被处理之前执行 *****</span>

filterChain.doFilter(servletRequest, wrapper);
// ***** 以下代码在请求被处理后前执行 *****
// 放入缓存
html = wrapper.getResult();
putIntoCache(key,html);
}

        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回响应</span>
        resp.setContentType("text/html; charset=utf-8"<span style="color: rgba(0, 0, 0, 1)">);
        resp.getWriter().print(html);
    } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
        filterChain.doFilter(servletRequest, resp);
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
    }
}

@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> destroy() {

}

</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String getHtmlFromCache(String redisKey) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> RedisUtil.get(redisKey);
}

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> putIntoCache(String redisKey,String html) {
    RedisUtil.set(redisKey, html,timeOut</span>*60<span style="color: rgba(0, 0, 0, 1)">);
}

}

 

 使用方式: 配置 web.xml

    <!-- 页面缓存配置 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>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">filter-mapping</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">filter-name</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>redisCachingFilter<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">filter-name</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">url-pattern</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>*.do<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">url-pattern</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">filter-mapping</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">filter-mapping</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">filter-name</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>redisCachingFilter<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">filter-name</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">url-pattern</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>*.action<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">url-pattern</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">filter-mapping</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>