Redis实现网页和json数据缓存

2019-07-09  本文已影响0人  你值得拥有更好的12138

以下均为本人理解,欢迎大佬指出错误
github地址:redis缓存网页和json数据

缓存的原理

缓存的数据包括网页和json数据

java层面需要的组件

1.一个fitler用于实现计数器和缓存的功能

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        String path = httpServletRequest.getServletPath();
        LOGGER.info("Recevice request path:" + path);

        try {
            //从缓存中取
             String jsonResult = (String) redisUtil.hget(JSON_CACHE, path);
            String pageResult = (String) redisUtil.hget(WEB_CACHE, path);
            double sorce = redisUtil.zIncreament(CACHE_COUNT, path, 1);
            LOGGER.info("Redis increment successfuly.");
            String result = Strings.isEmpty(pageResult) ? jsonResult : pageResult;
            if (!Strings.isEmpty(jsonResult)) {
                resp.setContentType("application/json; charset=utf-8");
            } else if (!Strings.isEmpty(pageResult)) {
                resp.setContentType("text/html; charset=utf-8");
            }

            if (Strings.isEmpty(result) && sorce > baseConfig.getClickCount()) {
                //当缓存中不存在,并且连接的使用次数超过阈值就进行缓存
                CacheResponseWrapper cacheResponseWrapper = new CacheResponseWrapper(resp);
                filterChain.doFilter(servletRequest, cacheResponseWrapper);
                jsonResult = cacheResponseWrapper.getBody();
                pageResult = cacheResponseWrapper.getBufferd();

                Map<String, String> cache = new HashMap<>();
                if (!Strings.isEmpty(jsonResult) && isJSONValid2(jsonResult)) {
                    //当结果是JSONResult
                    cache.put(path, jsonResult);
                    redisUtil.hmset(JSON_CACHE, cache);
                    resp.setContentType("application/json; charset=utf-8");
                    LOGGER.info("Redis cache json successfuly from path {}", path);
                } else {
                    //当结果是网页时
                    cache.put(path, pageResult);
                    redisUtil.hmset(WEB_CACHE, cache);

                    LOGGER.info("Redis cache page successfuly from path {}", path);
                }
                result = Strings.isEmpty(pageResult) ? jsonResult : pageResult;
                //将结果重新写入response,并提前结束避免调用 filterChain.doFilter(servletRequest, cacheResponseWrapper)报错
                resp.getWriter().write(result);
                return;
            } else {
                if(!Strings.isEmpty(result)){
                    LOGGER.info("Data from redis cache.");
                    resp.getWriter().write(result);
                    return;
                }else {
                    LOGGER.info("Path click count < 1");
                }
            }
        } catch (Exception e) {
            redisUtil.zadd(CACHE_COUNT, path, 1);
            LOGGER.error(e.getCause().toString());
            LOGGER.info("Redis add successfuly.");
        }
        filterChain.doFilter(servletRequest, resp);
    }

将结果重新写入response,并提前结束避免调用 filterChain.doFilter(servletRequest, cacheResponseWrapper)报错

2.CacheResponseWrapper extends HttpServletResponseWrapper 用于从response中获取请求的结果

public class CacheResponseWrapper extends HttpServletResponseWrapper {
    private CharArrayWriter bufferd;
    private PrintWriter printWriter;
    private ServletOutputStream outputStream;
    private ByteArrayOutputStream byteArrayOutputStream;

    public CacheResponseWrapper(HttpServletResponse response) {
        super(response);
        bufferd = new CharArrayWriter();
        printWriter = new PrintWriter(bufferd);
        byteArrayOutputStream = new ByteArrayOutputStream();
        outputStream = new ServletOutputStream() {
            @Override
            public void write(int b) throws IOException {
                byteArrayOutputStream.write(b);
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setWriteListener(WriteListener writeListener) {

            }
        };
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return printWriter;
    }

    public String getBufferd() {
        //普通请求方式使用这个获取结果
        return bufferd.toString();
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return outputStream;
    }

    public String getBody() {
        //json请求方式获取这个结果
        return new String(byteArrayOutputStream.toByteArray());
    }
}

3.操作redis的工具类
比如:

 public  boolean hmset(String key, Map<String, String> value) {
        boolean result = false;
        try {
            redisTemplate.opsForHash().putAll(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

上一篇下一篇

猜你喜欢

热点阅读