Java如何獲取真實請求IP
java獲取真實請求IP
在使用Nginx或Apache等代理的情況下,需要Nginx或Apache代替客戶端去訪問服務(wù)器。
當(dāng)請求包經(jīng)過反向代理后,在代理服務(wù)器這里這個IP數(shù)據(jù)包的IP包頭做了修改,最終后端WEB服務(wù)器得到的數(shù)據(jù)包的頭部源IP地址是代理服務(wù)器的IP地址。
這樣一來,后端服務(wù)器的程序就無法獲取用戶的真實ip。
nginx中配置:
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-Port $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Apache有代理的情況:
vi /usr/local/apache/conf/httpd.conf Include conf/extra/httpd-remoteip.conf vi /usr/local/apache/conf/extra/httpd-remoteip.conf LoadModule remoteip_module modules/mod_remoteip.so RemoteIPHeader X-Forwarded-For RemoteIPinternalProxy 127.0.0.1
- X-Real-IP 真實請求IP【Nginx中設(shè)置】
- X-Forwarded-For IP鏈,真實IP + , + 代理IP1.... + , + 代理IPN
- request.getRemoteAddr() 獲取真實IP/代理IP(用戶使用代理軟件時無法獲取真實IP)
真實請求IP
import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.UnknownHostException; public class IPUtil { /** * 真是請求IP * * @param request * @return */ public static String getRealRequestIp(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.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } if (null != ip && ip.contains(",")) { ip = ip.substring(0, ip.indexOf(",")); } return ip; } }
本機(jī)IP
???????import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.UnknownHostException; public class IPUtil { /** * 本機(jī)IP * * @return * @throws UnknownHostException */ public static String getLocalIp() throws UnknownHostException { return InetAddress.getLocalHost().getHostAddress(); } }
java獲取發(fā)送請求的電腦的IP地址
客戶端所有的請求信息都可以通過HttpServletRequest獲得,獲取客戶端ip可以通過getRemoteAddr()獲取。
但是如果客戶端是通過代理訪問我們的服務(wù)器,那么getRemoteAddr()獲取到的ip就很有可能不是真實的ip,這時候我們可以通過請求頭里的x-forwarded-for來獲取真實的ip,請求每經(jīng)一次代理,都會在后面拼接該代理的ip,以逗號分隔。
方法一
此方法獲取真實IP(本機(jī)IP并不是127.0.0.1)
獲取發(fā)送請求的電腦的IP地址,并返回
package com.lc.z.common.utils; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import javax.servlet.http.HttpServletRequest; public class IpUtil { /** * 獲取請求的ip */ public static String getRequestIp() { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // 從獲取RequestAttributes中獲取HttpServletRequest的信息 HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_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.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } }
方法二
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); String clientIP = ServletUtil.getClientIP(request); // 本地的服務(wù)輸出 IP:127.0.0.1 System.out.println("IP:"+ clientIP);
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot中的Condition包下常用條件依賴注解案例介紹
這篇文章主要介紹了SpringBoot中的Condition包下常用條件依賴注解案例,文章基于Java的相關(guān)資料展開主題詳細(xì)內(nèi)容,需要的小伙伴可以參考一下2022-04-04為了多次讀取ServletInputStream引發(fā)的一系列問題
這篇文章主要介紹了為了多次讀取ServletInputStream引發(fā)的一系列問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10restTemplate發(fā)送get與post請求并且?guī)?shù)問題
這篇文章主要介紹了restTemplate發(fā)送get與post請求并且?guī)?shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07java線程池:獲取運(yùn)行線程數(shù)并控制線程啟動速度的方法
下面小編就為大家?guī)硪黄猨ava線程池:獲取運(yùn)行線程數(shù)并控制線程啟動速度的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05解決Java項目啟動報錯:Logback?configuration?error?detected:問題
這篇文章主要介紹了解決Java項目啟動報錯:Logback?configuration?error?detected:問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04詳談Java枚舉、靜態(tài)導(dǎo)入、自動拆裝箱、增強(qiáng)for循環(huán)、可變參數(shù)
下面小編就為大家?guī)硪黄斦凧ava枚舉、靜態(tài)導(dǎo)入、自動拆裝箱、增強(qiáng)for循環(huán)、可變參數(shù)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08