SpringMVC通过Redis实现缓存主页
这里说的缓存只是为了提供一些动态的界面没办法作静态化的界面来减少数据库的访问压力,如果能够做静态化的话的还是采用nginx来做界面的静态化,这样可以承受高并发的访问能力。
好了,废话少说直接看实现代码吧下载地址,
实现机制主要是通过过滤器拦截方案,有两个地方要注意的
,Servlet过虑器中使用Spring容器
,截获JSP渲染结果保存redis中
首先看第一个Servlet过虑器中使用Spring容器
定义一个filter, 实现ApplicationContextAware接口 Java代码 收藏代码
public class CacheFilter implements Filter, ApplicationContextAware {
private static ApplicationContext ctx; // 必须声明为static
@Override
public void init(FilterConfig config) throws ServletException {
} @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() { }
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
CacheFilter.ctx = applicationContext; // 保存spring容器到static变量中
} 配置spring的bean
Java代码 收藏代码
<bean class="com.zhang.example.servlet.CacheFilter" id="cacheFilter"></bean> web.xml中的声明
Java代码 收藏代码
<filter>
<filter-name>Cache Filter</filter-name>
<filter-class>com.zhang.example.servlet.CacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Cache Filter</filter-name>
<servlet-name>/</servlet-name>
</filter-mapping> 这时,我们就可以在doFilter()方法中直接通过ApplicationContext检索需要的bean了
Java代码 收藏代码
StringRedisTemplate redis = (StringRedisTemplate)ctx.getBean("redisTemplate"); 二,截获JSP渲染结果
Java代码 收藏代码
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();
}
} Java代码 收藏代码
public class CacheFilter implements Filter, ApplicationContextAware {
private static final Logger log = LoggerFactory.getLogger(CacheFilter.class); private static ApplicationContext ctx;
@Override
public void init(FilterConfig config) throws ServletException {
} @Override
public 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);
}
@Override
public void destroy() {
} @Override
public 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分钟
}
}
按照这个逻辑,当客户的GET请求为/时,CacheFilter会首先向Redis发起请求获取主页的html代码,如果成功,则直接返回给客户端,失败,则通过刚刚写好的ResponseWrapper截获主页JSP的渲染结果,放入Redis,并设置过期时间为10分钟。这样下次请求时就可以直接从缓存中读取
SpringMVC通过Redis实现缓存主页的更多相关文章
- spring+springmvc+mybatis+redis实现缓存
先搭建好redis环境 需要的jar如下: jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:330 ...
- SpringMVC使用Redis作为缓存提供者
(1)pom添加依赖项 <dependency> <groupId>org.springframework.data</groupId> <artifactI ...
- SpringBoot集成Redis实现缓存处理(Spring AOP实现)
第一章 需求分析 计划在Team的开源项目里加入Redis实现缓存处理,因为业务功能已经实现了一部分,通过写Redis工具类,然后引用,改动量较大,而且不可以实现解耦合,所以想到了Spring框架的A ...
- mybatis-自定义缓存-redis二级缓存
在mybatis一级缓存二级缓存中已经介绍过了二级缓存的大致原理.下面我们用redis来实现一下二级缓存.环境是springmvc+mybatis+redis 步骤一.引入redis相关的maven依 ...
- springmvc+mybatis+redis实现查询插入操作
最近在学习redis,虽然现在还不是很熟练.不过可以进行简单的框架整合开发. IDE:我使用的是IDEA.springmvc+spring+mybatis的整合这个我就不多说了,下面我们先进行这块的整 ...
- springboot+redis实现缓存数据
在当前互联网环境下,缓存随处可见,利用缓存可以很好的提升系统性能,特别是对于查询操作,可以有效的减少数据库压力,Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存 ...
- 如何玩转最新的项目的搭配springmvc+mybatis+Redis+Nginx+tomcat+mysql
上一次完成nginx+tomcat组合搭配,今天我们就说说,这几个软件在项目中充当的角色: 要想完成这几个软件的组合,我们必须知道和熟悉应用这个框架, 一: Nginx:在项目中大多数作为反向代理服务 ...
- Springboot使用Shiro-整合Redis作为缓存 解决定时刷新问题
说在前面 (原文链接: https://blog.csdn.net/qq_34021712/article/details/80774649)本来的整合过程是顺着博客的顺序来的,越往下,集成的越多,由 ...
- SpringAOP与Redis搭建缓存
近期项目查询数据库太慢,持久层也没有开启二级缓存,现希望采用Redis作为缓存.为了不改写原来代码,在此采用AOP+Redis实现. 目前由于项目需要,只需要做查询部分: 数据查询时每次都需要从数据库 ...
随机推荐
- Thinkphp5——数据库表名的大小写问题
ThinkPHP5中数据库的表名如果是驼峰命名法,会被转换成小写加下划线,解决方法如下: 1.表名全部小写,因为数据库的表名区分大小写的. 2.使用Db::table("表名"), ...
- Python高级学习笔记
Python高级学习笔记,此笔记中包含Linux操作系统.Html+CSS+JS.网络协议等. 所有思维导图为本人亲手所画,请勿用于商用. 大哥们,求点赞哦. 第一天笔记:链接 第二天笔记:链接 第三 ...
- 链接脚本(Linker Script)应用实例(一)使用copy table将函数载入到RAM中运行
将函数载入到RAM中运行需要以下三个步骤: (1)用编译器命令#pragma section "<section name>" <user functions&g ...
- Nginx专题(2):Nginx的负载均衡策略及其配置
本文介绍了Nginx的负载均衡策略,一致性hash分配原理,及常用的故障节点的摘除与恢复配置. 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第一期-宜信支付结算八方数据团队高级技术经理 ...
- Java 中的 Servlet&Http&Request
# 今日内容 : 1. Servlet 2. HTTP 协议 3. Request (就是 Servlet 中 service 方法的 形参. (有这个)) ## Servlet : 1. 概 ...
- luogu P4462 [CQOI2018]异或序列 |莫队
题目描述 已知一个长度为n的整数数列a1,a2,...,an,给定查询参数l.r,问在al,al+1,...,ar区间内,有多少子序列满足异或和等于k.也就是说,对于所有的x,y (I ≤ x ≤ ...
- ACM中java中BigInteger和Decimal用到的主要函数
java中大数以及高精度常用函数 使用java大数类解决问题时我们需要注意两个方面:1.不能有包名,也就是说我们要把主类放到默认的包里,如果你的代码里出现形如package cn.gov.test;这 ...
- 洛谷 题解 P1372 【又是毕业季I】
这题... 只能说:n / k罢了... 但是: 代码没有最短,只有更短! #include <stdio.h> int n, k; int main() { return scanf(& ...
- InputStream 读取中文乱码 扩展
对于InputStream读取中文乱码,下面这段话给出了很好的解释,以及后续编码上的扩展. BufferedInputStream和BufferedOutputStream是过滤流,需要使用已存在的节 ...
- Day 08 作业
有如下值集合 [11, 22, 33, 44, 55, 66, 77, 88, 99, 90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中 ...