zoukankan      html  css  js  c++  java
  • SpringMVC通过Redis实现缓存主页

    这里说的缓存只是为了提供一些动态的界面没办法作静态化的界面来减少数据库的访问压力,如果能够做静态化的话的还是采用nginx来做界面的静态化,这样可以承受高并发的访问能力。 
         好了,废话少说直接看实现代码吧下载地址, 
         实现机制主要是通过过滤器拦截方案,有两个地方要注意的 
         1,Servlet过虑器中使用Spring容器 
         2,截获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)); // 10分钟  
        }  
    }  
    按照这个逻辑,当客户的GET请求为/时,CacheFilter会首先向Redis发起请求获取主页的html代码,如果成功,则直接返回给客户端,失败,则通过刚刚写好的ResponseWrapper截获主页JSP的渲染结果,放入Redis,并设置过期时间为10分钟。这样下次请求时就可以直接从缓存中读取
  • 相关阅读:
    HDU4366 Successor 线段树+预处理
    POJ2823 Sliding Window 单调队列
    HDU寻找最大值 递推求连续区间
    UVA846 Steps 二分查找
    HDU3415 Max Sum of MaxKsubsequence 单调队列
    HDU时间挑战 树状数组
    UVA10168 Summation of Four Primes 哥德巴赫猜想
    UESTC我要长高 DP优化
    HDUChess 递推
    HDU4362 Dragon Ball DP+优化
  • 原文地址:https://www.cnblogs.com/qingdouchukais/p/5166099.html
Copyright © 2011-2022 走看看