SpringMVC通过Redis实现缓存主页
来源:互联网 发布:域名 端口写法 编辑:程序博客网 时间:2024/06/07 00:43
http://blog.csdn.net/neosmith/article/details/46496353
首先,缓存主页的目的并不是提高性能,而是减少数据库访问压力,有效推迟数据库I/O瓶颈的到来。实现主页缓存的方法有很多,但是鉴于项目中使用了Redis对数据库读写做了缓存,因此把顺便也就把主页也缓存了吧。
实现思路
编写一个过滤器,在过滤器中拦截对主页的访问请求。此时向Redis服务器查询主页html的缓存,如果有则直接返回给客户端,如果没有,则在过滤器中截获JSP的渲染结果,放到Redis缓存中,以供下次使用。我们设定缓存过期时间为10分钟。
实现
实现需要注意的地方有两点:
如何在Servlet过虑器中使用Spring容器 如何截获JSP渲染结果
对于问题一,可以见我的另一篇博客:在Servlet Filter中使用Spring容器
对于问题二,我们可以继承HttpServletResponseWrapper类来巧妙实现:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 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);}@Overridepublic PrintWriter getWriter() { return cachedWriter;}/** * 获取原始的HTML页面内容。 * * @return */public String getResult() { return bufferedWriter.toString();}
}
然后在过滤器中使用该类:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public class CacheFilter implements Filter, ApplicationContextAware {
private static final Logger log = LoggerFactory.getLogger(CacheFilter.class);
private static ApplicationContext ctx;@Overridepublic void init(FilterConfig config) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse resp = (HttpServletResponse) servletResponse; HttpServletRequest req = (HttpServletRequest) servletRequest; // 如果不是访问主页,放行 if (false == req.getRequestURI().equals("/")) { filterChain.doFilter(servletRequest, resp); return; } // 访问的是主页 // 从缓存中得到主页html String html = getHtmlFromCache(); if (null == html) { // 缓存中没有 // 截取生成的html并放入缓存 log.info("缓存不存在,生成缓存"); ResponseWrapper wrapper = new ResponseWrapper(resp); // ***** 以上代码在请求被处理之前执行 ***** filterChain.doFilter(servletRequest, wrapper); // ***** 以下代码在请求被处理后前执行 ***** // 放入缓存 html = wrapper.getResult(); putIntoCache(html); } // 返回响应 resp.setContentType("text/html; charset=utf-8"); resp.getWriter().print(html);}@Overridepublic void destroy() {}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.ctx = applicationContext;}private String getHtmlFromCache() { StringRedisTemplate redis = (StringRedisTemplate)ctx.getBean("redisTemplate"); return redis.opsForValue().get("home");}private void putIntoCache(String html) { StringRedisTemplate redis = (StringRedisTemplate)ctx.getBean("redisTemplate"); redis.opsForValue().set("home", html, TimeUnit.MINUTES.toSeconds(10)); // 10分钟}
}
按照这个逻辑,当客户的GET请求为/时,CacheFilter会首先向Redis发起请求获取主页的html代码,如果成功,则直接返回给客户端,失败,则通过刚刚写好的ResponseWrapper截获主页JSP的渲染结果,放入Redis,并设置过期时间为10分钟。这样下次请求时就可以直接从缓存中读取,而不需要经过 Controller -> Service -> Dao -> Database这么费事的流程了。
- SpringMVC通过Redis实现缓存主页
- SpringMVC通过Redis实现缓存主页
- SpringMVC通过Redis实现缓存主页
- SpringMVC通过Redis实现缓存主页
- SpringMVC学习笔记3_通过redis缓存和cookie实现Session共享
- SpringMVC + redis缓存
- springMVC与redis事项缓存
- SpringMVC集成Redis缓存配置
- SpringMVC+Spring+mybatis+redis项目从零开始--redis缓存策略和配置实现
- SpringMVC+Spring+mybatis+redis项目从零开始--redis缓存策略和配置实现
- 11、Spring技术栈-整合Redis,通过Redis的Master-Slave实现缓存数据读写分离
- 通过spring-data-redis实现redis分布式缓存(增强版)
- redis实现缓存
- redis实现缓存
- spring + redis实现缓存
- mybatis缓存 redis实现
- MyBatis+Redis缓存实现
- REDIS实现数据缓存
- Android dp、sp转换为px的工具类
- Android中的网络请求:
- 在Servlet Filter中使用Spring容器
- 【LeetCode】Container with Most Water
- mysql优化之一(数据库设计)
- SpringMVC通过Redis实现缓存主页
- Windows下使用telnet命令发送邮件
- 数据结构实验之栈一:进制转换
- 深度学习与计算机视觉(11)_基于deep learning的快速图像检索系统
- vue父子组件互相传值
- 恶搞别人电脑关机
- Linux内核Makefile文件
- 哈希表及处理冲突的方法
- HDU 1172 猜数字