使用Java實(shí)現(xiàn)獲取客戶端IP地址
首先是獲取 IP,直接上代碼
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.UnknownHostException; /** * 獲取IP地址工具類 */ public final class IpUtil { private static final String UNKNOWN = "unknown"; private static final String IPV6_LOCAL = "::1"; // 推薦用壓縮形式 private IpUtil(){ throw new AssertionError(); } /** * 獲取請求用戶的IP地址 * @return */ public static String getRequestIp() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); return getRequestIp(request); } /** * 獲取請求用戶的IP地址 * @param request * @return */ public static String getRequestIp(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); // 處理多級代理,獲取第一個(gè)非 unknown 的有效 IP if (ip != null && !ip.isEmpty() && !UNKNOWN.equalsIgnoreCase(ip)) { ip = ip.split(",")[0].trim(); // 取第一個(gè) IP } else { ip = request.getHeader("X-Real-IP"); // 常見于 Nginx 代理 } // 備用方案:嘗試從其他頭部獲取 if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); // 默認(rèn)獲取遠(yuǎn)程地址 } // 如果是本地回環(huán)地址,則返回本地機(jī)器的 IP if (IPV6_LOCAL.equals(ip) || "127.0.0.1".equals(ip)) { ip = getLocalhostIp(); // 獲取本地 IP } return ip; } private static String getLocalhostIp() { try { InetAddress inetAddress = InetAddress.getLocalHost(); return inetAddress.getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); return "127.0.0.1"; // 如果無法獲取,則返回回環(huán)地址 } } }
但是今天發(fā)現(xiàn)一個(gè)問題,所有的地址都顯示為 127.0.0.1,我一琢磨應(yīng)該是 nginx 代理導(dǎo)致的,所以給 nginx 加上下面的配置
server { listen 80; server_name your-domain.com; location / { # 轉(zhuǎn)發(fā)客戶端的真實(shí) IP proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; # 代理轉(zhuǎn)發(fā)請求到網(wǎng)關(guān)服務(wù) proxy_pass http://localhost:1000/; } }
重啟 nginx 后再次請求就拿到了真實(shí)的 IP 地址了(注意所謂的真實(shí) IP 不一定真實(shí),這個(gè)東西是可以偽造的,至于防范措施大家自己去搜,道高一尺魔高一丈)
到此這篇關(guān)于使用Java實(shí)現(xiàn)獲取客戶端IP地址的文章就介紹到這了,更多相關(guān)Java獲取客戶端IP地址內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis遷移到Mybatis-Plus的實(shí)現(xiàn)方法
這篇文章主要介紹了Mybatis遷移到Mybatis-Plus的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08Java實(shí)現(xiàn)“年-月-日 上午/下午時(shí):分:秒”的簡單代碼
當(dāng)前的日期輸出的方法有很多,本文為大家介紹下在java中是如何實(shí)現(xiàn)“年-月-日 上午/下午時(shí):分:秒”,感興趣的朋友不妨參考下2015-08-08Java實(shí)現(xiàn)跳躍表(skiplist)的簡單實(shí)例
這篇文章主要介紹了Java編程中跳躍表的概念和實(shí)現(xiàn)原理,并簡要敘述了它的結(jié)構(gòu),具有一定參考價(jià)值,需要的朋友可以了解下。2017-09-09Java?OpenCV圖像處理之SIFT角點(diǎn)檢測詳解
SIFT,即尺度不變特征變換,是用于圖像處理領(lǐng)域的一種描述。這種描述具有尺度不變性,可在圖像中檢測出關(guān)鍵點(diǎn),是一種局部特征描述子。本文將詳細(xì)介紹一下Java?OpenCV圖像處理中的SIFT角點(diǎn)檢測,需要的可以參考一下2022-02-02Java使用ByteBuffer進(jìn)行多文件合并和拆分的代碼實(shí)現(xiàn)
因?yàn)轵?yàn)證證書的需要,需要把證書文件和公鑰給到客戶,考慮到多個(gè)文件交互的不便性,所以決定將2個(gè)文件合并成一個(gè)文件交互給客戶,但是由于是加密文件,采用字符串形式合并后,拆分后文件不可用,本文給大家介紹了Java使用ByteBuffer進(jìn)行多文件合并和拆分,需要的朋友可以參考下2024-09-09