java记录项目的UV值与PV值
2023-06-13 09:16:12 时间
一.什么是UV什么是PV
PV(访问量):Page View, 即页面浏览量或点击量,用户每次访问即被计算一次。 UV(独立访客):Unique Visitor,访问您网站的一台电脑客户端为一个访客。00:00-24:00内相同的客户端只会被计算一次。
二.为什么需要记录UV与PV
记录uv与pv可以更加直观的看到项目的访问量与用户的分布
三.怎么用java来实现UV与PV的记录
我的方式是通过过滤器的形式来获取到用户当前的真实ip,然后将ip+自己的写的rediskey一起存放进Reids里面,存入redis的有效期为当前时间离当天23:59:59的时间差(秒),这就是一个UV量,下次再请求的时候,通过ip从redis里面取值,如果取到了值,就证明该UV已记录,否则的话就是一个新的UV值
代码如下:
import com.jieyihua.common.core.constant.RedisConstant;
import com.jieyihua.common.core.utils.HttpUtils;
import com.jieyihua.common.core.utils.LocalDateTimeUtils;
import com.jieyihua.common.core.utils.StringUtils;
import com.jieyihua.common.redis.service.RedisService;
import com.jieyihua.system.api.RemoteStatisticsChannelService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author LiYu
* @version 3.0
* @description: APP端鉴权过滤器
* @date 2021/7/23 10:50
*/
@Slf4j
@WebFilter(urlPatterns = "/*", filterName = "appWebFilter")
@RequiredArgsConstructor
public class AppWebFilter implements Filter {
private final RemoteStatisticsChannelService remoteStatisticsChannelService;
private final RedisService redisService;
/**
* 开放接口
*/
private static final String[] OPEN_INTERFACE = {
"/open/",
};
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
//判断该请求是否拦截
AtomicBoolean whetherToIntercept = new AtomicBoolean(true);
//判断是否为开放接口
Arrays.asList(OPEN_INTERFACE).forEach(val -> {
if (request.getRequestURI().contains(val)) {
whetherToIntercept.set(false);
}
});
//不是开放接口 判断用户是否登陆
if (whetherToIntercept.get()) {
//获取请求token
String token = request.getHeader("Authorization");
//获取客户ID
String customerId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token) + "";
//双向绑定获取token
String originalToken = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
//获取客户名
String username = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token) + "";
//获取渠道ID
Long channelId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token);
//没有登陆
if (StringUtils.isEmpty(token)) {
throwOut("请先登录!", servletRequest, servletResponse);
} else if (StringUtils.isEmpty(customerId) || StringUtils.isEmpty(originalToken) || !originalToken.equals(token) || !StringUtils.hasText(username)) {
//在其他设备登陆了或者登陆过期了
throwOut("登录已过期或者在其他设备登录!", servletRequest, servletResponse);
} else {
//刷新缓存时间
redisService.moreUserCache(username, Long.parseLong(customerId), token,channelId);
//记录UV PV
//获取到用户的真实IP
String ip = HttpUtils.getIpAddress(request);
if(redisService.getCacheObject(RedisConstant.SYS_CUSTOMER_ONLY_IP+ip) == null){
//每天的凌晨00:00清除
redisService.setCacheObject(RedisConstant.SYS_CUSTOMER_ONLY_IP+ip,true, LocalDateTimeUtils.getTimeDifference(LocalDateTime.now(),LocalDateTimeUtils.getLocalDateTimeForEnd(LocalDateTime.now())), TimeUnit.SECONDS);
//增加一个UV
remoteStatisticsChannelService.addUv(channelId);
}
//增加一个pv
remoteStatisticsChannelService.addPv(channelId);
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
public void throwOut(String errorMessage, ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
// 将错误信息封装在request中
request.setAttribute("errorMessage", errorMessage);
// 请求转发
request.getRequestDispatcher("/error/systemError").forward(servletRequest, servletResponse);
}
}
相关文章
- (My)Eclipse 中的 Java 项目使用 .jardesc 文件快速导出 jar 包文件
- java高级工程师面试情景题_Java高级工程师面试题III
- java启动器_JAVA基础:Java 启动器如何查找类
- idea创建java项目_使用IDEA创建java项目(hello word)
- eclipse创建一个java项目目录_Eclipse创建JAVA项目
- xml格式化 java_Java XML格式化程序
- 【说站】java类中的两种成员访问
- Java的定时器_JAVA定时任务
- java的栈内存和堆内存_Java本地方法栈
- Java项目:CRM客户关系管理系统(Spring+SpringMVC+MyBatis + maven)
- 【错误记录】IntelliJ IDEA 编译 Groovy 项目报错 ( gradle-resources-test:XX: java.lang.NoClassDefFoundError: org )
- Java学习笔记 (异常相关知识)
- Java Activiti6.0 spring5 SSM 工作流引擎 审批流程 java项目框架详解编程语言
- 俄罗斯方块游戏完整Java源码详解编程语言
- Java经典实例:使用ChoiceFormat来格式化复数详解编程语言
- Linux环境下编译Java程序的指南(linux编译java)
- java.sql.SQLException: com.mysql.jdbc.Driver详解编程语言
- Linux下部署Java项目实践(linux部署java项目)
- Java程序更新MySQL记录的实践(java更新mysql)
- Linux 升级Java:新版本带来的变化(linux升级java)
- 时间Java中Redis实现的设置过期时间策略(redisjava过期)
- 使用Redis存储Java对象(redis存java对象)
- 时间设置Java实现Redis设置Key的过期时间(redisjava过期)
- Java与Linux:前景迷人的新科技(java和linux前景)
- Java编程操作Oracle数据库(java读oracle)
- 堆栈探索Java构建Oracle堆栈的可能性(java建oracle)
- 项目Java项目中展现Redis新型性能优势(redis运用在java)
- Java字节码指令集的使用详细
- java中sdk与jdk的区别详细解析