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

SpringBoot整合ip2region實(shí)現(xiàn)使用ip監(jiān)控用戶訪問城市的詳細(xì)過程

 更新時間:2022年07月07日 14:37:18   作者:summo  
這篇文章主要介紹了SpringBoot整合ip2region實(shí)現(xiàn)使用ip監(jiān)控用戶訪問城市,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

舉個栗子??

最近,多平臺都上線了展示近期發(fā)帖所在地功能,比如抖音、微博、百度,像下面那樣:

那么這個功能都是如何實(shí)現(xiàn)的呢?

一般有兩個方法:GPS 定位的信息和用戶 IP 地址。

由于每個手機(jī)都不一定會打開 GPS,而且有時并不太需要太精確的位置(到城市這個級別即可),所以根據(jù) IP 地址入手來分析用戶位置是個不錯的選擇。

所以ip2region框架應(yīng)運(yùn)而生,GitHub上??已經(jīng)10.6K,值得一用。

GitHub地址:github.com/lionsoul201…

快速上手??

第一步,將整個項(xiàng)目down下來,找到data目錄,進(jìn)入

這里有三份ip地址庫,我們將ip2region.xdb復(fù)制出來,等下我們的java項(xiàng)目中需要使用到。

第二步,創(chuàng)建maven項(xiàng)目,引入依賴

pom.xml依賴如下:

<!-- ip2region  -->
<dependency>
	<groupId>org.lionsoul</groupId>
	<artifactId>ip2region</artifactId>
    <version>2.6.3</version>
</dependency>
<!-- 用于讀取ip2region.xdb文件使用 -->
<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.6</version>
</dependency>

加好依賴后,在resources目錄下創(chuàng)建ip2region文件夾,把上面的ip2region.xdb文件放進(jìn)去。

第三步,編寫測試類

package com.example.springbootip.util;
import org.apache.commons.io.FileUtils;
import org.lionsoul.ip2region.xdb.Searcher;
import java.io.File;
import java.text.MessageFormat;
import java.util.Objects;
public class AddressUtil {
    /**
     * 當(dāng)前記錄地址的本地DB
     */
    private static final String TEMP_FILE_DIR = "/home/admin/app/";
    /**
     * 根據(jù)IP地址查詢登錄來源
     *
     * @param ip
     * @return
     */
    public static String getCityInfo(String ip) {
        try {
            // 獲取當(dāng)前記錄地址位置的文件
            String dbPath = Objects.requireNonNull(AddressUtil.class.getResource("/ip2region/ip2region.xdb")).getPath();
            File file = new File(dbPath);
            //如果當(dāng)前文件不存在,則從緩存中復(fù)制一份
            if (!file.exists()) {
                dbPath =    TEMP_FILE_DIR + "ip.db";
                System.out.println(MessageFormat.format("當(dāng)前目錄為:[{0}]", dbPath));
                file = new File(dbPath);
                FileUtils.copyInputStreamToFile(Objects.requireNonNull(AddressUtil.class.getClassLoader().getResourceAsStream("classpath:ip2region/ip2region.xdb")), file);
            }
            //創(chuàng)建查詢對象
            Searcher searcher = Searcher.newWithFileOnly(dbPath);
            //開始查詢
            return searcher.searchByStr(ip);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //默認(rèn)返回空字符串
        return "";
    }
    public static void main(String[] args) {
        System.out.println(getCityInfo("1.2.3.4"));
    }
}

輸出結(jié)果如下:

項(xiàng)目實(shí)現(xiàn)??

1、思路分析

通過上面簡單的例子我們已經(jīng)可以通過ip獲取地域了,那么接下來將實(shí)現(xiàn)如何監(jiān)控Controller接口的訪問地址。

首先,在一個項(xiàng)目中肯定有很多接口,所以我們不能直接在接口中寫代碼的方式去實(shí)現(xiàn),這樣代碼復(fù)雜度、耦合度太高。所以我打算在這里使用注解切面的方式實(shí)現(xiàn),只需要在接口方法上加上 @Ip 注解就可以實(shí)現(xiàn)。不知道切面是什么的同學(xué)可以參考這篇文章:Springboot如何使用Aspectj實(shí)現(xiàn)AOP面向切面編程

其次,有些項(xiàng)目中會使用Nginx等反向代理軟件,則不能通過 request.getRemoteAddr()獲取 IP地址,如果使用了多級反向代理的話,X-Forwarded-For的值并不止一個,而是一串IP地址,X-Forwarded-For中第一個非 unknown的有效IP字符串,則為真實(shí)IP地址。

最后,讓我們來實(shí)現(xiàn)這個功能吧!

2、配置文件

SpringBoot項(xiàng)目pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot-ip</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-ip</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

        <!-- ip2region -->
        <dependency>
            <groupId>org.lionsoul</groupId>
            <artifactId>ip2region</artifactId>
            <version>2.6.3</version>
        </dependency>
        <!-- aop切面 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3、項(xiàng)目代碼

項(xiàng)目結(jié)構(gòu)

SpringbootIpApplication.java

package com.example.springbootip;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootIpApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootIpApplication.class, args);
    }
}

TestController.java

package com.example.springbootip.controller;
import com.example.springbootip.ip2region.Ip;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
    @GetMapping("/hello")
    @Ip
    public String hello() {
        return "hello";
    }
}

Ip.java

package com.example.springbootip.ip2region;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Ip {
}

IpAspect.java

package com.example.springbootip.ip2region;
import com.example.springbootip.util.AddressUtil;
import com.example.springbootip.util.HttpContextUtil;
import com.example.springbootip.util.IPUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.text.MessageFormat;
@Aspect
@Component
public class IpAspect {
    @Pointcut("@annotation(com.example.springbootip.ip2region.Ip)")
    public void pointcut() {
        // do nothing
    }
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
        String ip = IPUtil.getIpAddr(request);
        System.out.println(MessageFormat.format("當(dāng)前IP為:[{0}];當(dāng)前IP地址解析出來的地址為:[{1}]", ip, AddressUtil.getCityInfo(ip)));
        return point.proceed();
    }
}

AddressUtil.java

package com.example.springbootip.util;
import org.apache.commons.io.FileUtils;
import org.lionsoul.ip2region.xdb.Searcher;
import java.io.File;
import java.text.MessageFormat;
import java.util.Objects;
public class AddressUtil {
    /**
     * 當(dāng)前記錄地址的本地DB
     */
    private static final String TEMP_FILE_DIR = "/home/admin/app/";
    /**
     * 根據(jù)IP地址查詢登錄來源
     *
     * @param ip
     * @return
     */
    public static String getCityInfo(String ip) {
        try {
            // 獲取當(dāng)前記錄地址位置的文件
            String dbPath = Objects.requireNonNull(AddressUtil.class.getResource("/ip2region/ip2region.xdb")).getPath();
            File file = new File(dbPath);
            //如果當(dāng)前文件不存在,則從緩存中復(fù)制一份
            if (!file.exists()) {
                dbPath =    TEMP_FILE_DIR + "ip.db";
                System.out.println(MessageFormat.format("當(dāng)前目錄為:[{0}]", dbPath));
                file = new File(dbPath);
                FileUtils.copyInputStreamToFile(Objects.requireNonNull(AddressUtil.class.getClassLoader().getResourceAsStream("classpath:ip2region/ip2region.xdb")), file);
            }
            //創(chuàng)建查詢對象
            Searcher searcher = Searcher.newWithFileOnly(dbPath);
            //開始查詢
            return searcher.searchByStr(ip);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //默認(rèn)返回空字符串
        return "";
    }
    public static void main(String[] args) {
        System.out.println(getCityInfo("1.2.3.4"));
    }
}

HttpContextUtil.java

package com.example.springbootip.util;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
 * @desc 全局獲取HttpServletRequest、HttpServletResponse
 */
public class HttpContextUtil {
    private HttpContextUtil() {
    }
    public static HttpServletRequest getHttpServletRequest() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
    }
    public static HttpServletResponse getHttpServletResponse() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
    }
}

IPUtil.java

package com.example.springbootip.util;
import javax.servlet.http.HttpServletRequest;
/**
 * @desc 查詢當(dāng)前訪問的IP地址
 */
public class IPUtil {
    private static final String UNKNOWN = "unknown";
    protected IPUtil() {
    }
    /**
     * 獲取 IP地址
     * 使用 Nginx等反向代理軟件, 則不能通過 request.getRemoteAddr()獲取 IP地址
     * 如果使用了多級反向代理的話,X-Forwarded-For的值并不止一個,而是一串IP地址,
     * X-Forwarded-For中第一個非 unknown的有效IP字符串,則為真實(shí)IP地址
     */
    public static String getIpAddr(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.getRemoteAddr();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }
}

打印結(jié)果

由于訪問路徑是:http://127.0.0.1:8080/test/hello,所以本地解析出來的是內(nèi)網(wǎng)

到此這篇關(guān)于SpringBoot整合ip2region實(shí)現(xiàn)使用ip監(jiān)控用戶訪問城市的文章就介紹到這了,更多相關(guān)SpringBoot整合ip2region內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于分布式鎖(Redisson)的原理分析

    關(guān)于分布式鎖(Redisson)的原理分析

    這篇文章主要介紹了關(guān)于分布式鎖(Redisson)的原理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java實(shí)現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法

    Java實(shí)現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法,方法通過實(shí)例代碼給大家介紹的非常詳細(xì),選擇使用哪種格式通常取決于項(xiàng)目的需求和上下文,所以格式轉(zhuǎn)換就成了我們必備的技能,具體實(shí)現(xiàn)代碼跟隨小編一起看看吧
    2023-10-10
  • java實(shí)現(xiàn)文件歸檔和還原

    java實(shí)現(xiàn)文件歸檔和還原

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)文件歸檔和還原,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • Java使用GUI繪制線條的示例

    Java使用GUI繪制線條的示例

    這篇文章主要介紹了Java使用GUI繪制線條的示例,幫助大家更好的理解和學(xué)習(xí)java gui編程,感興趣的朋友可以了解下
    2020-09-09
  • Idea中SpringBoot多模塊項(xiàng)目的建立實(shí)現(xiàn)

    Idea中SpringBoot多模塊項(xiàng)目的建立實(shí)現(xiàn)

    這篇文章主要介紹了Idea中SpringBoot多模塊項(xiàng)目的建立實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Idea導(dǎo)入多個maven項(xiàng)目到同一目錄下的方法示例

    Idea導(dǎo)入多個maven項(xiàng)目到同一目錄下的方法示例

    這篇文章主要介紹了Idea導(dǎo)入多個maven項(xiàng)目到同一目錄下,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Spring Bean如何實(shí)現(xiàn)自動配置代碼實(shí)例

    Spring Bean如何實(shí)現(xiàn)自動配置代碼實(shí)例

    這篇文章主要介紹了Spring Bean如何實(shí)現(xiàn)自動配置代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • Java開發(fā)實(shí)現(xiàn)人機(jī)猜拳游戲

    Java開發(fā)實(shí)現(xiàn)人機(jī)猜拳游戲

    這篇文章主要為大家詳細(xì)介紹了Java開發(fā)實(shí)現(xiàn)人機(jī)猜拳游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • 如何在Spring?Boot框架中使用攔截器實(shí)現(xiàn)URL限制

    如何在Spring?Boot框架中使用攔截器實(shí)現(xiàn)URL限制

    在Spring?Boot框架中,您可以使用攔截器(Interceptor)來控制限制URL列表,本文通過一個簡單的示例給大家介紹Spring?Boot?攔截器實(shí)現(xiàn)URL限制的操作方法,感興趣的朋友跟隨小編一起看看吧
    2023-08-08
  • vue 使用vuex在頁面跳轉(zhuǎn)的實(shí)現(xiàn)方式

    vue 使用vuex在頁面跳轉(zhuǎn)的實(shí)現(xiàn)方式

    這篇文章主要介紹了vue 使用vuex在頁面跳轉(zhuǎn)的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論

双城市| 景东| 平江县| 乐都县| 和平县| 吉水县| 华蓥市| 嘉善县| 宾阳县| 连南| 新乡市| 肥乡县| 连城县| 冀州市| 桐柏县| 渝中区| 奈曼旗| 衡东县| 万载县| 溧水县| 德州市| 安丘市| 山丹县| 景洪市| 广平县| 高雄市| 安西县| 家居| 东源县| 砚山县| 仪陇县| 余姚市| 黄龙县| 荣昌县| 商都县| 武义县| 阿图什市| 比如县| 平和县| 台江县| 深水埗区|