用java定时器实现记录用户访问页面时间

前阵子工作中遇到同事要记录用户访问网页页面时间的问题,后来仔细思考了一下,写了一个小demo,觉得应该记录下来。
思路:
考虑到用户访问除了正常关闭或离开页面之外还有停电断网的情况,所以最好的办法是用前端定时心跳请求法记录用户访问状态。
1.在前端公共js里设置一个定时器,每隔一段时间(这个可以根据业务自调)定时向后台访问一个url
2.后台设置一个公用map,用来记录每个用户的访问状态,map里记录有每个用户的开始页面访问时间和每个用户离开页面的时间,怎么判断用户离开页面呢,在后台用java写一个定时器,项目启动时同时启用定时器,每隔一段时间(这个可以根据业务自调)扫描map里每个用户的访问时间,用系统当前时间和map里的最后一次访问时间做比对,当超过一定时间(这个可以根据业务自调)时,表明用户已经离开页面,记录下当前用户最后一次访问时间做离开页面的时间,然后map里就有了当前用户的访问时间,离开页面时间.
3.接下来可以计算停留时间保存进数据库,在数据库保存时做累计,或者直接把用户信息保存在数据库(这个根据业务实现怎么样的功能而定).
4.最后remove掉已保存进数据库的那些用户信息。

理论上map里同时存在离开页面的用户和当前访问页面的用户,通过java定时扫描的方式,记录下离开页面的用户信息并移除map里的离线用户。

代码(用SSI框架为例):
1.前端公用js里写一个定时器:

setInterval(function(){
        //要执行的代码 
        var nameText = $(".adminControl").text();
        console.log(nameText.split(",")[1]);
        var paramObj = {};
        paramObj.userName = /*nameText.split(",")[1]*/"开始健";
        //发送请求
        $.ajax({
               type: "POST",
               url: ctx+"/getUserTime.do",
               data: paramObj,
               success: function(data){
                   
               },
               error:function(){
                   
               }
            });
       console.log("定时器已生效");                   
    },5000);

2.controller里声明两个变量。

public class ConfigVersionQueryController extends BaseController{
    
    protected final Log log = LogFactory.getLog(ConfigVersionQueryController.class);
    @Autowired
    private ConfigVersionQueryService service;
    @Autowired
    private ConfigGlobalService globalService;
    @Autowired
    private IModuleLogManager logManager; 
    
    private static Map timeMap = new HashMap();
    private static int value = 0;

}

3.写一个记录用户时间的接口:

/**
     * 记录用户时间
     * @return
     * @throws Exception
     */
    @RequestMapping("/getUserTime.do")
    public void getUserTime(HttpServletRequest request,HttpServletResponse response) throws Exception
    {
        value++;
        String userName = request.getParameter("userName");
        if(null == timeMap.get(userName)){
            //用户开始访问时间
            timeMap.put(userName + "startTime", new Date());
        }
        timeMap.put(userName, new Date());
        
        //System.out.println("用户开始访问时间=" + timeMap.get(userName + "startTime"));
        //System.out.println("用户请求时间=" + timeMap.get(userName));
       // System.out.println(value);
        if(value == 1){
            System.out.println("进来===");
            Timer timer = new Timer();
             timer.schedule(new TimerTask() {
                  public void run() {
                     // server
                      System.out.println("-------设定要指定任务--------");
                      Iterator iter = timeMap.entrySet().iterator();        //获取key和value的set
                      Date time = null;
                      System.out.println("==="+ timeMap.size());
                      Set keySet = new HashSet();
                      while (iter.hasNext()) {
                          Map.Entry entry = (Map.Entry) iter.next();        //把hashmap转成Iterator再迭代到entry
                          String key = entry.getKey().toString();       //从entry获取key
                          if(key.indexOf("startTime") == -1 ){
                              time = (Date) entry.getValue();
                              if(((new Date()).getTime() - time.getTime())/1000 > 9){
                                  keySet.add(key);
                              } 
                          }
                      }
                      for (String key : keySet) {
                          System.out.println(key + "访问页面时间==" + (Date)timeMap.get(key + "startTime"));
                          System.out.println(key +"离开页面时间==" + (Date)timeMap.get(key));
                          //此处省略计入数据库的操作,可以计算停留时间等
                          //保存进数据库之后移除离线用户信息
                          timeMap.remove(key);
                          timeMap.remove(key + "startTime"); 
                       } 
                  }
                }, 15000, 15000);// 设定指定的时间time,此处为15000毫秒
        }
    }

总结:此为实验小demo,实现过程中用userId更好,这里只是为了直观起见用了userName,为了测试方便,前端设定固定请求时间为5秒,当前时间和最后一次记录时间差为9秒,后台定时器每15秒扫描一次,实际项目中这些时间都可以根据业务自调。

你可能感兴趣的:(用java定时器实现记录用户访问页面时间)