版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41376740/article/details/82054391
需求
为了提高数据的访问速度,我们经常会把有一些数据放进缓存里面,读取磁盘的速度要比读取内存的速度慢很多,说到缓存我便想到了redis,于是便有了把一段jsp页面的内容缓存进redis里面的想法。顺便解决了TCP,TIME_Wait的问题
思路
1、来了一个访问请求,filter进行拦截。先判断redis里面有没有需要的数据。
2、如果有,就读出缓存的数据,写给浏览器,将请求拦截。
3、如果没有,就取出返回给浏览器的数据,并且使用redis进行缓存。
关键点
1、包装模式增强response的write方法,从而捕获需要访问的数据
2、缓存逻辑
代码
package xiao.web.filter;
import redis.clients.jedis.Jedis;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
@WebFilter(filterName = "RedisCacheFilter", urlPatterns = "/redis.jsp")
public class RedisCacheFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
String value = getRedis("test1");
if (value != null) {
System.out.println("用缓存");
response.getWriter().write(value);
}else {
CacheResponse cacheResponse = new CacheResponse(response);
chain.doFilter(request, cacheResponse);
String cachedValue = cacheResponse.getResult();
setRedis("test1", cacheResponse.getResult());
response.getWriter().write(cachedValue);
}
}
public void init(FilterConfig config) throws ServletException {
}
public String getRedis(String key) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
String value = jedis.get(key);
jedis.close();
return value;
}
public void setRedis(String key, String value) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.set(key, value);
jedis.close();
}
}
class CacheResponse extends HttpServletResponseWrapper {
// 捕获输出的字符流
private CharArrayWriter cacheWriter = new CharArrayWriter();
public CacheResponse(HttpServletResponse response) {
super(response);
}
@Override
public PrintWriter getWriter() throws IOException {
return new PrintWriter(cacheWriter, true);
}
public String getResult() {
if (this.cacheWriter != null) {
return this.cacheWriter.toString();
}
return null;
}
}
redis效果:
java给我们提供了一个wrapper包装类,里面已经用了包装设计模式,维护了response对象,所以我们这里没有必要再设置response,每次调用response的getWriter会获得我们实现设置好的Writer,调用write方法就写进CharArrayWriter里面,方便以后获取。jedis是一个简单的java访问redis的库。这里只做了最简单的连接使用。
遇到的问题-超时连接
1、问题来源:ssl
@Test
public void testGetRedis() throws Exception {
Jedis jedis = new Jedis("127.0.0.1", 6379, true);
System.out.println(jedis.get("test"));
jedis.close();
}
在new Jedis的时候,开启了ssl,于是一直报错显示连接超时,永远停留在了get那行代码,经过查资料,jedis虽然有ssl的选项,但是依赖于服务器端redis的配置,而redis自身不带ssl,所以我们就不用ssl了,mysql连接的时候我一直用了useSSL=true,所以这次也习惯性地用上了