你好呀,我是小鄒。
在現代的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
package com.zou.blog.util;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** ip解析工具** @author zxf* @version v1.0.0* @date 2024/7/14 20:26*/
@Slf4j
public class IpParseUtil {/*** 解析ip地址** @param ipStr 字符串類型ip 例:192.168.0.1* @return 返回結果形式(國家 | 區域 | 省份 | 城市 | ISP) 例 [中國, 0, 河北省, 衡水市, 電信]*/public static List<String> parse(String ipStr) {return parse(ipStr, null);}/*** 自定義解析ip地址** @param ipStr ip 字符串類型ip 例:1970753539(經過轉換后的)* @param index 想要獲取的區間 例如:只想獲取 省,市 index = [2,3]* @return 返回結果例 [北京,北京市]*/public static List<String> parse(String ipStr, int[] index) {try {//獲得文件流時,因為讀取的文件是在打好jar文件里面,不能直接通過文件資源路徑拿到文件,但是可以在jar包中拿到文件流//ResourcePatternResolver的實現方法,可以匹配到各種部署時的各種文件類型例如war,jar,zip等等findPathMatchingResourcesResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();Resource[] resources = resolver.getResources("ip2region.xdb");Resource resource = resources[0];InputStream is = resource.getInputStream();File target = new File("ip2region.xdb");FileUtils.copyInputStreamToFile(is, target);is.close();Searcher searcher = new Searcher(String.valueOf(target), null, null);long ip = Searcher.checkIP(ipStr);return parse(ip, index, searcher);} catch (Exception e) {log.error("ip解析為long錯誤,ipStr:[{}],錯誤信息:[{}]", ipStr, e.getMessage(), e);throw new RuntimeException("系統異常!");}}/*** 自定義解析ip地址** @param ip ip Long類型ip* @param index 想要獲取的區間 例如:只想獲取 省,市 index = [2,3]* @return 返回結果例 [湖南省, 衡陽市]*/public static List<String> parse(Long ip, int[] index, Searcher searcher) {List<String> regionList = new ArrayList<>();try {String region = searcher.search(ip);log.info("獲取到的城市信息:" + region);String[] split = region.split("\\|");if (index == null) {regionList = Arrays.asList(split);} else {for (int i : index) {regionList.add(split[i]);}}//關閉資源searcher.close();} catch (Exception e) {log.error("根據ip解析地址失敗,ip:[{}],index[{}],報錯信息:[{}]", ip, index, e.getMessage(), e);throw new RuntimeException("系統異常!");}return regionList;}/*** 獲取IP方法** @author zxf*/public static String getIpAddr(HttpServletRequest request) {if (request == null) {return "unknown";}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("X-Forwarded-For");}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("X-Real-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return ip;}public static void main(String[] args) {String ip = "218.20.32.122";List<String> parse = parse(ip);System.out.println(parse);}}
關鍵方法解析:
-
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
字段。
// 在評論控制器中
@PostMapping("/comments")
public ResponseEntity<Comment> createComment(@RequestBody Comment comment, HttpServletRequest request) {String ip = IpParseUtil.getIpAddr(request);List<String> location = IpParseUtil.parse(ip);comment.setLocation(location);// ...保存評論到數據庫...
}
顯示位置信息:
在前端展示評論時,從location
字段讀取并顯示信息。
<!-- 前端HTML示例 -->
<div class="comment"><p>By: {{ comment.user.name }}</p><p>Location: {{ comment.location.join(", ") }}</p><p>{{ comment.content }}</p>
</div>
通過上述步驟,我們成功實現了在博客評論中顯示用戶地址信息的功能,這不僅增加了博客的互動性,還為用戶提供了一種直觀的地理位置參考。使用Java和ip2region
庫,我們可以高效準確地解析IP地址并獲取地理位置信息,從而提升用戶體驗和網站的吸引力。