网站访问量统计功能的实现

实现方法:拦截器+session存储

拦截器初始化时,即在@PostConstruct注解的initMethod方法中读取数据库的isystem对象,该对象记录了网站访问量的信息。

拦截器销毁时,即在@PreDestroy注解的destroyMethod方法中向数据库更新isystem对象。

拦截器的初始化和销毁都只有在应用启动和关闭的时候才被调用,因此减少了对数据库的访问。

SpringMVC中,每一次请求控制器,都会先执行拦截器的preHandle方法,在该方法内先查看session中的一个标志accessedFlag,如果该标志不存在,说明此次会话没有被统计,因此在isystem对象中增加一次访问量,并向session添加标志accessedFlag,下一次访问时,该session不再添加访问量,即一个session算访问一次。并且在session中存储isystem对象,并于网页显示数据的调用。

为了保证并发的正确性,局部代码块使用同步锁,见下面红色部分。

总结:拦截器有一个静态属性isystem,用户第一次请求时,都会更新这个属性的值。用户的每一次请求都会把该属性放入到用户的session中去。因此,B用户第一次访问后,A用户第二次访问时(和第一次访问共享一个session),A用户的session中的isystem也会被更新。

拦截器类如下:

package com.wuchao.utils.interceptor;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.wuchao.blog.system.bo.intf.IsystemBo;
import com.wuchao.blog.system.po.Isystem;
import com.wuchao.blog.user.controller.LoginController;
import com.wuchao.utils.config.SpringContextHolder;

public class RequestInterceptor extends HandlerInterceptorAdapter {
	private static Logger log = Logger.getLogger(LoginController.class);  
	
	@Resource(name="isystemBo")
	public IsystemBo isystemBo;	
	@Resource(name="springContextHolder")
	SpringContextHolder  springContextHolder;
	
	public static Isystem isystem;

	//请求控制器前,处理请求
	@Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
		try {
			log.info("RequestInterceptor");
			//网站访问量+1
			if(isystem==null) {
				log.info("isystem==null");
				isystem = isystemBo.getIsystemByDefault();
			}
			if(isystem!=null) {
				//每一个session理论上只能记一次访问,因此在session里面存一个访问标记,如果存在标记,则不再计算此次访问
				String accessedFlag = "accessedFlag";
				if(request.getSession().getAttribute("accessedFlag")==null) {
					//同步锁
					synchronized(this) {
						log.info("网站访问量+1,存入session");
						isystem.setAmountOfAccess(isystem.getAmountOfAccess()+1);
						request.getSession().setAttribute("Isystem", isystem);
						request.getSession().setAttribute("accessedFlag", accessedFlag);
					}
					
				}
			}	
			
		}catch(Exception e) {
			e.printStackTrace();
			throw e;
		}

        return true;
    }

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		
	}
	
	/*
	 * 实例化时执行的操作
	 */
	@PostConstruct  
    public void initMethod() throws Exception {  
        log.info("initMethod 被执行");  
        //加载isystem对象
		if(isystem==null) {
			log.info("加载isystem");
			isystem = isystemBo.getIsystemByDefault();
		}
    } 
	/*
	 * 销毁前执行的操作
	 */
    @PreDestroy  
    public void destroyMethod() throws Exception {  
    	log.info("destroyMethod 被执行");  
    	//保存isystem
    	if(isystem!=null) {
    		isystemBo.saveIsystem(isystem);
    	}
    }  
}
原文地址:https://www.cnblogs.com/wuchaodzxx/p/7172321.html