最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot輕松實現(xiàn)ip解析(含源碼)

 更新時間:2023年10月23日 09:39:21   作者:fking86  
IP地址一般以數(shù)字形式表示,如192.168.0.1,IP解析是將這個數(shù)字IP轉(zhuǎn)換為包含地區(qū)、城市、運(yùn)營商等信息的字符串形式,如“廣東省深圳市 電信”,這樣更方便人理解和使用,本文給大家介紹了SpringBoot如何輕松實現(xiàn)ip解析,需要的朋友可以參考下

應(yīng)用場景

(1)網(wǎng)站訪問分析

可以解析用戶IP地址,分析網(wǎng)站訪問量的地域分布,以便進(jìn)行針對性推廣。

(2)欺詐風(fēng)險控制

某地區(qū)IP地址多次進(jìn)行惡意刷單、刷票等行為,可以通過IP地址解析加以攔截。

(3)限制服務(wù)區(qū)域

解析用戶IP地址,限制僅為某地區(qū)的用戶提供服務(wù)。

(4)顯示訪問者來源

在博客、論壇等,解析并顯示每個帖子的發(fā)帖人來自哪個地區(qū)。

下面帶大家實踐在spring boot 項目中獲取請求的ip與詳細(xì)地址。

示例

前期準(zhǔn)備

引用框架:Ip2region

下載地址: https://gitee.com/lionsoul/ip2region.git

注意:如果需要離線獲取需要下載 /data/ip2region.xdb 文件

Ip2region 特性

1、IP 數(shù)據(jù)管理框架

xdb 支持億級別的 IP 數(shù)據(jù)段行數(shù),默認(rèn)的 region 信息都固定了格式:國家|區(qū)域|省份|城市|ISP,缺省的地域信息默認(rèn)是0。 region 信息支持完全自定義,例如:你可以在 region 中追加特定業(yè)務(wù)需求的數(shù)據(jù),例如:GPS信息/國際統(tǒng)一地域信息編碼/郵編等。也就是你完全可以使用 ip2region 來管理你自己的 IP 定位數(shù)據(jù)。

2、數(shù)據(jù)去重和壓縮

xdb 格式生成程序會自動去重和壓縮部分?jǐn)?shù)據(jù),默認(rèn)的全部 IP 數(shù)據(jù),生成的 ip2region.xdb 數(shù)據(jù)庫是 11MiB,隨著數(shù)據(jù)的詳細(xì)度增加數(shù)據(jù)庫的大小也慢慢增大。

3、極速查詢響應(yīng)

即使是完全基于 xdb 文件的查詢,單次查詢響應(yīng)時間在十微秒級別,可通過如下兩種方式開啟內(nèi)存加速查詢:

  1. vIndex 索引緩存 :使用固定的 512KiB 的內(nèi)存空間緩存 vector index 數(shù)據(jù),減少一次 IO 磁盤操作,保持平均查詢效率穩(wěn)定在10-20微秒之間。
  2. xdb 整個文件緩存:將整個 xdb 文件全部加載到內(nèi)存,內(nèi)存占用等同于 xdb 文件大小,無磁盤 IO 操作,保持微秒級別的查詢效率。

版本依賴

框架名版本號
SpringBoot3.1.4
jdk17
tomcat-embed-core10.1.8
lombok1.18.26
fastjson1.2.73
ip2region2.7.0

導(dǎo)入庫

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

<!--ip庫-->
<dependency>
    <groupId>org.lionsoul</groupId>
    <artifactId>ip2region</artifactId>
    <version>2.7.0</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>10.1.8</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.26</version>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.73</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
</dependency>

具體代碼

Constant

public interface Constant {

    // IP地址查詢
    public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
    /**
     * 本地ip
     */
    public static final String LOCAL_IP = "127.0.0.1";


    /**
     * 數(shù)據(jù)庫訪問地址
     */
    public static final String DB_PATH = "springboot-ip/src/main/resources/ip2region/ip2region.xdb";
}

AddressUtils(在線解析)

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;

import static com.example.springbootip.constant.Constant.IP_URL;
import static com.example.springbootip.constant.Constant.LOCAL_IP;

/**
 * @author coderJim
 * @date 2023-10-16 14:07
 */
@Slf4j
public class AddressUtils {

    // 未知地址
    public static final String UNKNOWN = "XX XX";

    public static String getRealAddressByIP(String ip) {
        String address = UNKNOWN;
        // 內(nèi)網(wǎng)不查詢
        if (ip.equals(LOCAL_IP)) {
            return "內(nèi)網(wǎng)IP";
        }
        if (true) {
            try {
                String rspStr = sendGet(IP_URL, "ip=" + ip + "&json=true" ,"GBK");
                if (StringUtils.isEmpty(rspStr)) {
                    log.error("獲取地理位置異常 {}" , ip);
                    return UNKNOWN;
                }
                JSONObject obj = JSONObject.parseObject(rspStr);
                String region = obj.getString("pro");
                String city = obj.getString("city");
                return String.format("%s %s" , region, city);
            } catch (Exception e) {
                log.error("獲取地理位置異常 {}" , ip);
            }
        }
        return address;
    }

    public static String sendGet(String url, String param, String contentType) {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            log.info("sendGet - {}" , urlNameString);
            URL realUrl = new URL(urlNameString);
            URLConnection connection = realUrl.openConnection();
            connection.setRequestProperty("accept" , "*/*");
            connection.setRequestProperty("connection" , "Keep-Alive");
            connection.setRequestProperty("user-agent" , "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            log.info("recv - {}" , result);
        } catch (ConnectException e) {
            log.error("調(diào)用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
        } catch (SocketTimeoutException e) {
            log.error("調(diào)用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
        } catch (IOException e) {
            log.error("調(diào)用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
        } catch (Exception e) {
            log.error("調(diào)用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception ex) {
                log.error("調(diào)用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }
}

IpUtil(離線解析)

import static com.example.springbootip.constant.Constant.DB_PATH;
import static com.example.springbootip.constant.Constant.LOCAL_IP;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * @author coderJim
 * @date 2023-10-16 11:02
 */
@Slf4j
public class IpUtil {

    protected IpUtil(){ }

    /**
     * 獲取 IP地址
     * 使用 Nginx等反向代理軟件, 則不能通過 request.getRemoteAddr()獲取 IP地址
     * 如果使用了多級反向代理的話,X-Forwarded-For的值并不止一個,而是一串IP地址,
     * X-Forwarded-For中第一個非 unknown的有效IP字符串,則為真實IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals(LOCAL_IP)) {
                    // 根據(jù)網(wǎng)卡取本機(jī)配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        log.error(e.getMessage(), e);
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 對于通過多個代理的情況,第一個IP為客戶端真實IP,多個IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }

        return ipAddress;
    }

    public static  String getAddr(String ip) {
        String project_dir = System.getProperty("user.dir") +"";
        String dbPath = project_dir + "/" + DB_PATH;
        // 1、從 dbPath 加載整個 xdb 到內(nèi)存。
        byte[] cBuff;
        try {
            cBuff = Searcher.loadContentFromFile(dbPath);
        } catch (Exception e) {
            log.info("failed to load content from `%s`: %s\n", dbPath, e);
            return null;
        }

        // 2、使用上述的 cBuff 創(chuàng)建一個完全基于內(nèi)存的查詢對象。
        Searcher searcher;
        try {
            searcher = Searcher.newWithBuffer(cBuff);
        } catch (Exception e) {
            log.info("failed to create content cached searcher: %s\n", e);
            return null;
        }
        // 3、查詢
        try {
            String region = searcher.search(ip);
            return region;
        } catch (Exception e) {
            log.info("failed to search(%s): %s\n", ip, e);
        }
        return null;
    }

}

IpController

import com.example.springbootip.util.AddressUtils;
import com.example.springbootip.util.IpUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.*;

/**
 * @author coderJim
 */
@RestController
@RequestMapping("/demo")
public class IpController {
    
    @ResponseBody
    @GetMapping("/realAddress")
    public String realAddress(HttpServletRequest request){
        String ip = IpUtil.getIpAddr(request);
        //在線獲取
//        String realAddress = AddressUtils.getRealAddressByIP(ip);
        //離線獲取
        String realAddress = IpUtil.getAddr(ip);
        return "您的ip所在地為:"+ realAddress;
    }
}

執(zhí)行結(jié)果

運(yùn)行請求 http://127.0.0.1:8080/demo/realAddress

如果執(zhí)行:

String realAddress = AddressUtils.getRealAddressByIP(ip);

顯示結(jié)果:

您的ip所在地為:浙江省 杭州市

如果執(zhí)行:

String realAddress = IpUtil.getAddr(ip);

顯示結(jié)果:

您的ip所在地為:中國|0|浙江省|杭州市|電信

總結(jié)

通過這樣的一套流程下來,我們就能實現(xiàn)對每一個請求進(jìn)行ip 獲取、ip解析

以上就是SpringBoot輕松實現(xiàn)ip解析(含源碼)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot實現(xiàn)ip解析的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot添加自定義攔截器的實現(xiàn)代碼

    SpringBoot添加自定義攔截器的實現(xiàn)代碼

    這篇文章主要介紹了SpringBoot添加自定義攔截器的實現(xiàn)代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-09-09
  • java實現(xiàn)Excel高性能異步導(dǎo)出的完整方案詳解

    java實現(xiàn)Excel高性能異步導(dǎo)出的完整方案詳解

    在大型電商系統(tǒng)中,數(shù)據(jù)導(dǎo)出是一個高頻且重要的功能需求,本文將設(shè)計實現(xiàn)一套完整的Excel異步導(dǎo)出機(jī)制,通過注解驅(qū)動、任務(wù)隊列、定時調(diào)度、消息通知等技術(shù)手段,完美解決了大數(shù)據(jù)量導(dǎo)出的技術(shù)難題,成為項目的重要技術(shù)亮點
    2025-10-10
  • springboot下mybatis-plus如何打印sql日志和參數(shù)到日志文件

    springboot下mybatis-plus如何打印sql日志和參數(shù)到日志文件

    本文主要介紹了springboot下mybatis-plus如何打印sql日志和參數(shù)到日志文件,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java 實現(xiàn)Excel文檔添加超鏈接的代碼

    Java 實現(xiàn)Excel文檔添加超鏈接的代碼

    超鏈接即內(nèi)容鏈接,通過給特定對象設(shè)置超鏈接,可實現(xiàn)載體與特定網(wǎng)頁、文件、郵件、網(wǎng)絡(luò)等的鏈接,點擊鏈接載體可打開鏈接目標(biāo),在文檔處理中是一種比較常用的功能,本文將介紹通過Java程序給Excel文檔添加超鏈接的方法,感興趣的朋友一起看看吧
    2020-02-02
  • SpringBoot實現(xiàn)異步消息處理的代碼示例

    SpringBoot實現(xiàn)異步消息處理的代碼示例

    在現(xiàn)代應(yīng)用程序中,異步消息處理是一項至關(guān)重要的任務(wù)。它可以提高應(yīng)用程序的性能、可伸縮性和可靠性,同時也可以提供更好的用戶體驗,本文將介紹如何使用Spring Boot實現(xiàn)異步消息處理,并提供相應(yīng)的代碼示例
    2023-06-06
  • 使用SpringMVC訪問Controller接口返回400BadRequest

    使用SpringMVC訪問Controller接口返回400BadRequest

    這篇文章主要介紹了使用SpringMVC訪問Controller接口返回400BadRequest,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 完美解決idea沒有tomcat server選項的問題

    完美解決idea沒有tomcat server選項的問題

    這篇文章主要介紹了完美解決idea沒有tomcat server選項的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • java中的引用類型之強(qiáng)軟弱虛詳解

    java中的引用類型之強(qiáng)軟弱虛詳解

    這篇文章主要給大家介紹了關(guān)于java中引用類型之強(qiáng)軟弱虛的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Ubuntu安裝JDK與IntelliJ?IDEA的詳細(xì)過程

    Ubuntu安裝JDK與IntelliJ?IDEA的詳細(xì)過程

    APT是Linux系統(tǒng)上的包管理工具,能自動解決軟件包依賴關(guān)系并從遠(yuǎn)程存儲庫中獲取安裝軟件包,這篇文章主要介紹了Ubuntu安裝JDK與IntelliJ?IDEA的過程,需要的朋友可以參考下
    2023-08-08
  • mybatis中#{}和${}的區(qū)別詳解

    mybatis中#{}和${}的區(qū)別詳解

    本文主要介紹了mybatis中#{}和${}的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論

东阳市| 策勒县| 富裕县| 宁乡县| 景洪市| 昭苏县| 汽车| 赣榆县| 平度市| 栾川县| 湘阴县| 甘洛县| 佛学| 通海县| 云霄县| 安泽县| 龙里县| 绥棱县| 革吉县| 大余县| 同仁县| 定陶县| 曲阳县| 两当县| 万安县| 丹寨县| 盐池县| 乐清市| 东安县| 贵州省| 邢台县| 武功县| 苍梧县| 乾安县| 道真| 梨树县| 连江县| 汕尾市| 黄骅市| 铁岭县| 丰城市|