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

本文介绍了一种解决用户访问网页时长记录的方法,通过前端定时心跳请求和后端Java定时器配合。前端每隔固定时间发送请求,后端使用Map存储用户访问状态,并通过定时器检查用户是否离开页面,超时则记录离开时间并保存至数据库。
摘要由CSDN通过智能技术生成

前阵子工作中遇到同事要记录用户访问网页页面时间的问题,后来仔细思考了一下,写了一个小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秒扫描一次,实际项目中这些时间都可以根据业务自调。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值