SpringBoot联合ip2region实现博客品评显示IP属地

打印 上一主题 下一主题

主题 1712|帖子 1712|积分 5136

你好呀,我是小邹。
在今世的Web应用中,特别是博客和论坛类网站,为用户提供地理定位服务(如显示用户地点地理位置)可以极大地增强用户体验。本文将详细探究怎样利用Java和相关技术栈来实现在博客品评中显示用户的地点信息,特别关注怎样利用ip2region库解析IP地点获取地理位置。
效果图:


技术栈:



  • 后端框架:Spring Boot
  • 数据库:MySQL
  • 前端技术:HTML, CSS, JavaScript
  • 地理编码库:ip2region
  • 辅助库:Apache Commons IO, Lombok
代码分析:IpParseUtil 类

这个类位于com.zou.blog.util包下,提供了几个关键方法用于解析IP地点并获取用户的地理位置信息。
ip2region文件:https://github.com/lionsoul2014/ip2region/blob/master/data/ip2region.xdb
  1. package com.zou.blog.util;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.commons.io.FileUtils;
  4. import org.lionsoul.ip2region.xdb.Searcher;
  5. import org.springframework.core.io.Resource;
  6. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  7. import org.springframework.core.io.support.ResourcePatternResolver;
  8. import javax.servlet.http.HttpServletRequest;
  9. import java.io.File;
  10. import java.io.InputStream;
  11. import java.util.ArrayList;
  12. import java.util.Arrays;
  13. import java.util.List;
  14. /**
  15. * ip解析工具
  16. *
  17. * @author zxf
  18. * @version v1.0.0
  19. * @date 2024/7/14 20:26
  20. */
  21. @Slf4j
  22. public class IpParseUtil {
  23.     /**
  24.      * 解析ip地址
  25.      *
  26.      * @param ipStr 字符串类型ip 例:192.168.0.1
  27.      * @return 返回结果形式(国家 | 区域 | 省份 | 城市 | ISP) 例 [中国, 0, 河北省, 衡水市, 电信]
  28.      */
  29.     public static List<String> parse(String ipStr) {
  30.         return parse(ipStr, null);
  31.     }
  32.     /**
  33.      * 自定义解析ip地址
  34.      *
  35.      * @param ipStr ip 字符串类型ip 例:1970753539(经过转换后的)
  36.      * @param index 想要获取的区间 例如:只想获取 省,市 index = [2,3]
  37.      * @return 返回结果例 [北京,北京市]
  38.      */
  39.     public static List<String> parse(String ipStr, int[] index) {
  40.         try {
  41.             //获得文件流时,因为读取的文件是在打好jar文件里面,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流
  42.             //ResourcePatternResolver的实现方法,可以匹配到各种部署时的各种文件类型例如war,jar,zip等等findPathMatchingResources
  43.             ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  44.             Resource[] resources = resolver.getResources("ip2region.xdb");
  45.             Resource resource = resources[0];
  46.             InputStream is = resource.getInputStream();
  47.             File target = new File("ip2region.xdb");
  48.             FileUtils.copyInputStreamToFile(is, target);
  49.             is.close();
  50.             Searcher searcher = new Searcher(String.valueOf(target), null, null);
  51.             long ip = Searcher.checkIP(ipStr);
  52.             return parse(ip, index, searcher);
  53.         } catch (Exception e) {
  54.             log.error("ip解析为long错误,ipStr:[{}],错误信息:[{}]", ipStr, e.getMessage(), e);
  55.             throw new RuntimeException("系统异常!");
  56.         }
  57.     }
  58.     /**
  59.      * 自定义解析ip地址
  60.      *
  61.      * @param ip    ip Long类型ip
  62.      * @param index 想要获取的区间 例如:只想获取 省,市 index = [2,3]
  63.      * @return 返回结果例 [湖南省, 衡阳市]
  64.      */
  65.     public static List<String> parse(Long ip, int[] index, Searcher searcher) {
  66.         List<String> regionList = new ArrayList<>();
  67.         try {
  68.             String region = searcher.search(ip);
  69.             log.info("获取到的城市信息:" + region);
  70.             String[] split = region.split("\\|");
  71.             if (index == null) {
  72.                 regionList = Arrays.asList(split);
  73.             } else {
  74.                 for (int i : index) {
  75.                     regionList.add(split[i]);
  76.                 }
  77.             }
  78.             //关闭资源
  79.             searcher.close();
  80.         } catch (Exception e) {
  81.             log.error("根据ip解析地址失败,ip:[{}],index[{}],报错信息:[{}]", ip, index, e.getMessage(), e);
  82.             throw new RuntimeException("系统异常!");
  83.         }
  84.         return regionList;
  85.     }
  86.     /**
  87.      * 获取IP方法
  88.      *
  89.      * @author zxf
  90.      */
  91.     public static String getIpAddr(HttpServletRequest request) {
  92.         if (request == null) {
  93.             return "unknown";
  94.         }
  95.         String ip = request.getHeader("x-forwarded-for");
  96.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  97.             ip = request.getHeader("Proxy-Client-IP");
  98.         }
  99.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  100.             ip = request.getHeader("X-Forwarded-For");
  101.         }
  102.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  103.             ip = request.getHeader("WL-Proxy-Client-IP");
  104.         }
  105.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  106.             ip = request.getHeader("X-Real-IP");
  107.         }
  108.         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  109.             ip = request.getRemoteAddr();
  110.         }
  111.         return ip;
  112.     }
  113.     public static void main(String[] args) {
  114.         String ip = "218.20.32.122";
  115.         List<String> parse = parse(ip);
  116.         System.out.println(parse);
  117.     }
  118. }
复制代码
关键方法解析:

  • parse(String ipStr) 方法

    • 接收一个字符串类型的IP地点,如"192.168.0.1"。
    • 返回一个列表,其中包罗解析得到的地理位置信息,格式为:[国家, 区域, 省份, 城市, ISP]。

  • parse(String ipStr, int[] index) 方法

    • 提供了更灵活的参数index,允许开发者选择返回特定范围的信息,例如仅省份和城市。
    • 返回一个列表,只包罗由index参数指定的地理位置信息部门。

  • getIpAddr(HttpServletRequest request) 方法

    • 从HTTP请求中提取客户端的IP地点,思量到可能存在的署理服务器环境。

集成到博客品评体系:

要在博客品评中显示用户的位置信息,你可以在处置处罚品评提交的控制器中集成IpParseUtil类的方法。

  • 获取IP地点
    在品评提交的控制器中,利用getIpAddr方法从HTTP请求中获取用户IP地点。
  • 解析IP地点
    调用parse方法解析IP地点,获取用户的地理位置信息。
  • 生存位置信息
    将解析得到的位置信息生存至品评模子中,如Comment实体的location字段。
  1. // 在评论控制器中
  2. @PostMapping("/comments")
  3. public ResponseEntity<Comment> createComment(@RequestBody Comment comment, HttpServletRequest request) {
  4.     String ip = IpParseUtil.getIpAddr(request);
  5.     List<String> location = IpParseUtil.parse(ip);
  6.     comment.setLocation(location);
  7.     // ...保存评论到数据库...
  8. }
复制代码
显示位置信息:

在前端展示品评时,从location字段读取并显示信息。
  1. <!-- 前端HTML示例 -->
  2. <div class="comment">
  3.     <p>By: {{ comment.user.name }}</p>
  4.     <p>Location: {{ comment.location.join(", ") }}</p>
  5.     <p>{{ comment.content }}</p>
  6. </div>
复制代码
通过上述步调,我们成功实现了在博客品评中显示用户地点信息的功能,这不光增长了博客的互动性,还为用户提供了一种直观的地理位置参考。利用Java和ip2region库,我们可以高效准确地解析IP地点并获取地理位置信息,从而提拔用户体验和网站的吸引力。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

不到断气不罢休

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表