• 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分钟。这样下次请求时就可以直接从缓存中读取
  • 相关阅读:
    小试SQLServer中的CLR特性
    转:memcached命令行参数说明
    2012年9月19日最新整理的日本产品(日货)名单!
    转:Memcached Java Client API详解
    刚写的一个小案例,实现多选的添加及删除
    SVG中的常用标签
    转:网页启用Gzip压缩 提高浏览速度
    SVG案例:著名的PostScript老虎图片
    SVG文档:SVG编程经典教程(转)
    实用技巧:利用SQL Server的扩展属性自动生成数据字典
  • 原文地址:https://www.cnblogs.com/qingdouchukais/p/5166099.html
Copyright © 2020-2023  润新知