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

SpringBoot獲取瀏覽器信息的多種實(shí)現(xiàn)方式

 更新時(shí)間:2025年10月24日 10:08:40   作者:匆匆忙忙游刃有余  
在Web開發(fā)中,獲取用戶瀏覽器信息是常見需求,可用于統(tǒng)計(jì)分析、個(gè)性化展示、安全防護(hù)等場景,SpringBoot提供了多種方式來獲取這些信息,下面是詳細(xì)實(shí)現(xiàn)方法,需要的朋友可以參考下

引言

在Web開發(fā)中,獲取用戶瀏覽器信息是常見需求,可用于統(tǒng)計(jì)分析、個(gè)性化展示、安全防護(hù)等場景。SpringBoot提供了多種方式來獲取這些信息,下面是詳細(xì)實(shí)現(xiàn)方法。

一、獲取基本請求信息

1. 獲取客戶端IP地址

在SpringBoot中,最基本的方法是通過HttpServletRequest對象獲取IP地址,但需要注意反向代理的情況。

public class IpUtils {
    private static final String UNKNOWN = "unknown";
    
    /**
     * 獲取真實(shí)IP地址(考慮反向代理情況)
     */
    public static String getIpAddr(HttpServletRequest request) {
        if (request == null) {
            return UNKNOWN;
        }
        
        // 嘗試從各種代理頭中獲取IP
        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("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        
        // 如果還是沒有獲取到,使用RemoteAddr
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        
        // 處理多級代理的情況,取第一個(gè)IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        
        // 本地測試情況
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        
        return ip;
    }
}

2. 獲取請求頭信息

@RestController
public class BrowserInfoController {
    
    @GetMapping("/browser-info")
    public Map<String, String> getBrowserInfo(HttpServletRequest request) {
        Map<String, String> info = new HashMap<>();
        
        // 獲取IP地址
        info.put("ip", IpUtils.getIpAddr(request));
        
        // 獲取User-Agent
        info.put("userAgent", request.getHeader("User-Agent"));
        
        // 獲取其他請求頭信息
        info.put("accept", request.getHeader("Accept"));
        info.put("acceptLanguage", request.getHeader("Accept-Language"));
        info.put("referer", request.getHeader("Referer"));
        info.put("contentType", request.getHeader("Content-Type"));
        info.put("encoding", request.getHeader("Accept-Encoding"));
        info.put("connection", request.getHeader("Connection"));
        
        return info;
    }
}

二、使用UserAgentUtils解析瀏覽器信息

1. 添加依賴

<!-- pom.xml -->
<dependency>
    <groupId>eu.bitwalker</groupId>
    <artifactId>UserAgentUtils</artifactId>
    <version>1.21</version>
</dependency>

2. 解析瀏覽器詳細(xì)信息

public class BrowserUtils {
    
    /**
     * 解析瀏覽器信息
     */
    public static Map<String, Object> parseBrowserInfo(String userAgentString) {
        Map<String, Object> result = new HashMap<>();
        
        // 創(chuàng)建UserAgent對象
        UserAgent userAgent = UserAgent.parseUserAgentString(userAgentString);
        
        // 獲取瀏覽器信息
        Browser browser = userAgent.getBrowser();
        Version browserVersion = userAgent.getBrowserVersion();
        result.put("browser", browser.getName());
        result.put("browserVersion", browserVersion.getVersion());
        
        // 獲取操作系統(tǒng)信息
        OperatingSystem os = userAgent.getOperatingSystem();
        result.put("operatingSystem", os.getName());
        
        // 獲取設(shè)備信息
        DeviceType deviceType = os.getDeviceType();
        result.put("deviceType", deviceType.getName());
        
        // 判斷是否是移動設(shè)備
        result.put("isMobile", os.isMobileDevice());
        
        // 獲取渲染引擎
        RenderingEngine engine = userAgent.getRenderingEngine();
        result.put("renderingEngine", engine.name());
        
        return result;
    }
}

3. 在Controller中使用

@RestController
public class BrowserInfoController {
    
    @GetMapping("/detailed-browser-info")
    public Map<String, Object> getDetailedBrowserInfo(HttpServletRequest request) {
        Map<String, Object> info = new HashMap<>();
        
        // 獲取IP
        String ip = IpUtils.getIpAddr(request);
        info.put("ip", ip);
        
        // 獲取并解析User-Agent
        String userAgentString = request.getHeader("User-Agent");
        Map<String, Object> browserDetails = BrowserUtils.parseBrowserInfo(userAgentString);
        info.putAll(browserDetails);
        
        return info;
    }
}

三、獲取IP地址歸屬地

1. 使用ip2region庫(本地解析)

添加依賴:

<dependency>
    <groupId>org.lionsoul</groupId>
    <artifactId>ip2region</artifactId>
    <version>2.6.3</version>
</dependency>

實(shí)現(xiàn)代碼:

public class IpRegionUtils {
    private static Searcher searcher;
    
    // 初始化ip2region
    static {
        try {
            // 下載xdb文件到resources目錄
            String dbPath = IpRegionUtils.class.getResource("/ip2region.xdb").getPath();
            // 創(chuàng)建searcher對象
            searcher = Searcher.newWithFileOnly(dbPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 獲取IP地址歸屬地
     */
    public static String getCityInfo(String ip) {
        if (searcher == null || ip == null) {
            return "未知";
        }
        
        try {
            long startTime = System.nanoTime();
            String region = searcher.search(ip);
            long endTime = System.nanoTime();
            System.out.printf("IP: %s, 歸屬地: %s, 耗時(shí): %f 微秒\n", 
                             ip, region, (endTime - startTime) / 1000000.0);
            return region;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "未知";
    }
    
    // 程序結(jié)束時(shí)釋放資源
    public static void close() {
        if (searcher != null) {
            try {
                searcher.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2. 使用第三方API(在線解析)

public class IpLocationUtils {
    private static final String IP_API_URL = "https://api.ip2location.com/v2/?key=YOUR_API_KEY&ip=%s&package=WS3"
    
    /**
     * 通過第三方API獲取IP歸屬地
     */
    public static String getIpLocation(String ip) {
        try {
            String url = String.format(IP_API_URL, ip);
            String result = HttpUtil.get(url);
            // 解析JSON結(jié)果
            JSONObject jsonObject = JSON.parseObject(result);
            String country = jsonObject.getString("country_name");
            String region = jsonObject.getString("region_name");
            String city = jsonObject.getString("city_name");
            return country + " " + region + " " + city;
        } catch (Exception e) {
            e.printStackTrace();
            return "未知";
        }
    }
}

四、創(chuàng)建統(tǒng)一的瀏覽器信息工具類

@Component
public class ClientInfoUtil {
    
    /**
     * 獲取完整的客戶端信息
     */
    public Map<String, Object> getClientInfo() {
        HttpServletRequest request = getCurrentRequest();
        if (request == null) {
            return Collections.emptyMap();
        }
        
        Map<String, Object> clientInfo = new HashMap<>();
        
        // 獲取IP地址
        String ip = IpUtils.getIpAddr(request);
        clientInfo.put("ip", ip);
        
        // 獲取IP歸屬地
        clientInfo.put("location", IpRegionUtils.getCityInfo(ip));
        
        // 獲取并解析User-Agent
        String userAgentString = request.getHeader("User-Agent");
        Map<String, Object> browserInfo = BrowserUtils.parseBrowserInfo(userAgentString);
        clientInfo.putAll(browserInfo);
        
        // 獲取其他有用信息
        clientInfo.put("sessionId", request.getSession().getId());
        clientInfo.put("requestUrl", request.getRequestURL().toString());
        clientInfo.put("referer", request.getHeader("Referer"));
        clientInfo.put("timestamp", System.currentTimeMillis());
        
        return clientInfo;
    }
    
    /**
     * 獲取當(dāng)前請求
     */
    private HttpServletRequest getCurrentRequest() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        if (attributes instanceof ServletRequestAttributes) {
            return ((ServletRequestAttributes) attributes).getRequest();
        }
        return null;
    }
}

五、實(shí)際應(yīng)用場景

1. 訪問日志記錄

@Aspect
@Component
@Slf4j
public class AccessLogAspect {
    
    @Autowired
    private ClientInfoUtil clientInfoUtil;
    
    @Pointcut("execution(* com.example.controller.*.*(..))")
    public void logPointCut() {}
    
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();
        
        // 獲取客戶端信息
        Map<String, Object> clientInfo = clientInfoUtil.getClientInfo();
        
        // 執(zhí)行目標(biāo)方法
        Object result = point.proceed();
        
        // 記錄訪問日志
        long endTime = System.currentTimeMillis();
        log.info("訪問日志: {}", JSON.toJSONString(clientInfo));
        log.info("處理時(shí)間: {}ms", endTime - startTime);
        
        return result;
    }
}

2. 安全驗(yàn)證中間件

@Component
public class SecurityCheckFilter extends OncePerRequestFilter {
    
    @Autowired
    private ClientInfoUtil clientInfoUtil;
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, 
                                    FilterChain filterChain) throws ServletException, IOException {
        
        // 獲取客戶端信息
        Map<String, Object> clientInfo = clientInfoUtil.getClientInfo();
        
        // 進(jìn)行安全檢查(示例:檢查是否是異常瀏覽器)
        String browser = (String) clientInfo.get("browser");
        if ("不支持的瀏覽器".equals(browser)) {
            response.setStatus(403);
            response.getWriter().write("不支持的瀏覽器,請使用主流瀏覽器訪問");
            return;
        }
        
        // 繼續(xù)過濾鏈
        filterChain.doFilter(request, response);
    }
}

六、注意事項(xiàng)

  1. 反向代理處理:在使用Nginx等反向代理時(shí),需要正確配置代理頭,確保能獲取到真實(shí)IP
  2. 性能考慮:IP歸屬地查詢可能影響性能,建議使用緩存
  3. 隱私保護(hù):獲取用戶信息時(shí)要遵守相關(guān)隱私法規(guī)
  4. 依賴更新:UserAgentUtils庫已停止維護(hù),可考慮使用其他替代方案如yauaa
  5. 錯(cuò)誤處理:網(wǎng)絡(luò)請求和解析過程中要做好異常處理

通過以上方法,你可以在SpringBoot項(xiàng)目中全面獲取和處理瀏覽器相關(guān)信息,為應(yīng)用提供更豐富的功能和更好的用戶體驗(yàn)。

到此這篇關(guān)于SpringBoot獲取瀏覽器信息的多種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)SpringBoot獲取瀏覽器信息內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring自定義注解實(shí)現(xiàn)數(shù)據(jù)脫敏

    Spring自定義注解實(shí)現(xiàn)數(shù)據(jù)脫敏

    在當(dāng)今數(shù)據(jù)安全越來越受到重視的背景下,許多企業(yè)都對敏感數(shù)據(jù)的保護(hù)有著嚴(yán)格的要求,本文就來深入探討一下如何自定義注解來實(shí)現(xiàn)對敏感數(shù)據(jù)的脫敏處理吧
    2024-11-11
  • 詳解Spring Security認(rèn)證流程

    詳解Spring Security認(rèn)證流程

    這篇文章主要介紹了Spring Security認(rèn)證流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • JAVA Spring中讓人頭痛的JAVA大事務(wù)問題要如何解決你知道嗎

    JAVA Spring中讓人頭痛的JAVA大事務(wù)問題要如何解決你知道嗎

    這篇文章主要介紹了Java Spring事務(wù)使用及驗(yàn)證過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-09-09
  • springboot項(xiàng)目同時(shí)啟動web服務(wù)和grpc服務(wù)的方法

    springboot項(xiàng)目同時(shí)啟動web服務(wù)和grpc服務(wù)的方法

    本文主要介紹了springboot項(xiàng)目同時(shí)啟動web服務(wù)和grpc服務(wù)的方法,通過實(shí)際代碼示例展示了實(shí)現(xiàn),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • SpringBoot集成支付寶沙箱支付(支付、退款)

    SpringBoot集成支付寶沙箱支付(支付、退款)

    這篇文章主要為大家詳細(xì)介紹了SpringBoot集成支付寶沙箱支付,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 超詳細(xì)講解Java異常

    超詳細(xì)講解Java異常

    Java 異常機(jī)制可以使程序中異常處理代碼和正常業(yè)務(wù)代碼分離,保證程序代碼更加優(yōu)雅,并提高程序健壯性。本文超詳細(xì)講解了Java異常,感興趣的小伙伴可以參考一下這篇文章
    2021-09-09
  • SpringBoot用多線程批量導(dǎo)入數(shù)據(jù)庫實(shí)現(xiàn)方法

    SpringBoot用多線程批量導(dǎo)入數(shù)據(jù)庫實(shí)現(xiàn)方法

    這篇文章主要介紹了SpringBoot用多線程批量導(dǎo)入數(shù)據(jù)庫實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • 關(guān)于Java for循環(huán)的正確用法介紹

    關(guān)于Java for循環(huán)的正確用法介紹

    Java里的循環(huán)結(jié)構(gòu)我們可以通過while、do-while、for、foreach等方式實(shí)現(xiàn)循環(huán),這篇文章會把這幾種循環(huán)方式都給大家講解到,但本文主要介紹for循環(huán)的使用,感興趣的同學(xué)可以參考閱讀
    2023-05-05
  • eclipse創(chuàng)建springboot項(xiàng)目的三種方式總結(jié)

    eclipse創(chuàng)建springboot項(xiàng)目的三種方式總結(jié)

    這篇文章主要介紹了eclipse創(chuàng)建springboot項(xiàng)目的三種方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring Boot集成Spring Cloud Security進(jìn)行安全增強(qiáng)的方法

    Spring Boot集成Spring Cloud Security進(jìn)行安全增強(qiáng)的方法

    Spring Cloud Security是Spring Security的擴(kuò)展,它提供了對Spring Cloud體系中的服務(wù)認(rèn)證和授權(quán)的支持,包括OAuth2、JWT等,這篇文章主要介紹了Spring Boot集成Spring Cloud Security進(jìn)行安全增強(qiáng),需要的朋友可以參考下
    2024-11-11

最新評論

白玉县| 伊金霍洛旗| 射阳县| 沿河| 留坝县| 苍山县| 福泉市| 府谷县| 新沂市| 郎溪县| 萍乡市| 新宁县| 昆山市| 平江县| 拉萨市| 揭阳市| 五原县| 肇源县| 兴宁市| 兴仁县| 镇康县| 信阳市| 长岭县| 萨迦县| 广水市| 平乡县| 莱芜市| 九江市| 和静县| 安平县| 什邡市| 息烽县| 集贤县| 中阳县| 田东县| 无为县| 丹凤县| 永昌县| 正安县| 嘉义县| 仁化县|