炫酷,Spring Boot + ECharts 实现用户访问地图可视化(附源码)
时间:2022-07-28
本文章向大家介绍炫酷,Spring Boot + ECharts 实现用户访问地图可视化(附源码),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
来源 | https://www.toutiao.com/i6845433908494860804/
意义
- 在常见的电商、新闻、社交网站等,合理运用运营成本才能最大化输出自己的产品,其中最常见的功能就有针对不同访问热度的城市制定不同的运营手段,因此我们掌握用户城市分布情况至关重要。
- pc端与移动端不同,无法依托手机自带的gps定位到用户所在城市,只能通过ip来进行判断所在地理位置。
根据ip获取城市的方式
- 淘宝、新浪等常年提供根据ip获取城市的接口,但是隔一段时间会出现接口地址更改的情况,也有一定的限流
- 开源纯真ip库:不断迭代更新ip库内容,一般场景下足以使用,自主可控。(下载qqwry.dat库)
思路
首先需要获取用户请求的ip地址,我们对该方法进行简单封装:
public class IPUtil {
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
推荐一个DD长期连载的Spring Boot基础教程:http://blog.didispace.com/spring-boot-learning-2x/
封装纯真ip的解析工具,根据ip获取请求地址所在城市,github有大量实现版本,我们这里不做赘述,具体代码见文末源码
//篇幅较长,截取的主要方法,详细在源码地址查看
public IPZone findIP(final String ip) {
final long ipNum = toNumericIP(ip);
final QIndex idx = searchIndex(ipNum);
if (idx == null) {
return new IPZone(ip);
}
return readIP(ip, idx);
}
自定义拦截器,对用户的登录请求进行拦截,在此处判断请求ip所在城市,并进行计数。我们这里只是简单逻辑的说明,在生产上时应该用redis来存放计数,并且专门提供一个rest接口来推送当前各城市访问数量情况,再由前端配合,隔一段时间发起一次请求,例如隔一小时请求一次该rest接口,从而进行前端数据的展示。
/**
* 登录拦截器
*/
@Slf4j
public class MyLoginInterceptor implements HandlerInterceptor {
private static final String LOGIN_PATH = "/user/login";
private static Map<String, AtomicInteger> visitCount;
private static final QQWry qqWry;
static {
visitCount = new HashMap<>(31);
qqWry = new QQWry();
}
//展示访问数量不是精确指标,如果要做到完全正确需要使用锁,防止计数存在并发问题
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("【MyLoginInterceptor】调用了:{}", request.getRequestURI());
if (request.getRequestURI().equals(LOGIN_PATH)) {
String ipAddress = IPUtil.getIpAddress(request);
String province = qqWry.findIP(ipAddress).getMainInfo();
if (visitCount.containsKey(province)) {
visitCount.put(province,new AtomicInteger(visitCount.get(province).incrementAndGet()));
} else {
visitCount.put(province,new AtomicInteger());
}
}
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){}
}
注册自定义的拦截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyLoginInterceptor());
}
}
登录controller模拟逻辑,注意:如果想看效果图需要自己写线程用不同的虚拟ip进行访问url,从而达到在不同城市访问接口的效果。
@RestController("user")
public class LoginController {
@GetMapping("login")
public String login() {
//登录逻辑
return "success";
}
}
案例源码
https://github.com/Motianshi/distribute-tool
- Jquery 获取第一个子元素
- Dropwizard框架入门
- Java 解析Excel文件为JSON
- SQL语句大小写是否区分的问题,批量修改整个数据库所有表所有字段大小写
- CentOS 6.5 安装nginx 1.6.3
- C#创建数字证书并导出为pfx,并使用pfx进行非对称加解密
- MyBatis两张表字段名相同产生的问题
- mongo 3.0 备份和还原数据库 ,及too many positional arguments错误
- AngularJs HTTP响应拦截器实现登陆、权限校验
- C# 读写App.config配置文件的方法
- Golang语言社区--Go语言基础第四节类型
- Golang语言社区--go语言编写Web程序
- Golang语言社区--Go语言基础第五节流程控制
- (14)不同基因坐标转换-生信菜鸟团博客2周年精选文章集
- HTML 教程
- HTML 简介
- html div 标签介绍
- html span 标签介绍
- html a 超链接标签
- HTML Br换行标签介绍
- HTML P段落标签介绍
- HTML br与p标签区别
- Html H 标题标签
- html px em pt长度单位
- HTML form 标签
- HTML radio 单选框
- HTML B 加粗标签
- HTML strong加粗粗体标签
- HTML em 强调标签
- HTML i 斜体标签
- HTML u下划线标签
- HTML s 删除线标签
- Html img 图片标签
- Html上标注sup与下标注sub标签
- HTML nobr 禁止换行标签
- HTML hr 水平线标签
- HTML label 标签
- HTML input 标签
- HTML textarea 标签
- HTML select下拉列表标签
- HTML checkbox 多选框
- HTML font color 标签
- HTML iframe 框架标签
- HTML Table 表格
- HTML dl dt dd 标签
- HTML ol li有序列表标签
- HTML ul li 无序列表标签
- HTML 注释
- CSS 教程
- CSS 简介
- CSS 语法
- CSS Id 和 Class选择器
- CSS 样式的创建
- CSS background 背景介绍
- CSS 文本样式
- CSS font 字体
- CSS A 链接
- CSS ul ol列表样式
- CSS TABLE 样式
- CSS 框模型
- CSS border 边框
- CSS Outlines 轮廓
- CSS 外边距 Margin
- CSS Padding 内边距
- CSS 分组和嵌套选择器
- CSS 尺寸 (Dimension)
- CSS Display 属性
- CSS Position 定位
- CSS Float 浮动
- CSS 水平对齐(Horizontal Align)
- CSS 组合选择符
- CSS 伪类
- CSS 伪元素
- CSS 导航栏
- CSS 下拉菜单
- CSS 图片廊
- CSS 图像透明/不透明
- CSS sprite 图像拼合技术
- CSS 媒体类型
- CSS 属性选择器
- CSS 实例