nginx代理模式下java獲取客戶端真實ip地址實例代碼
一、簡要概述
獲取客戶端ip地址是開發(fā)中常見的功能需求,獲取ip地址后,一般可以記錄日志備查或者針對ip做訪問控制。nginx代理模式下,如何獲取客戶端真實ip地址呢?
二、Java代碼
為了簡單起見,我們封裝了restful接口,用來直接返回ip,核心代碼如下
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class IndexController
{
@Autowired
HttpServletRequest request;
@GetMapping({"/", "/index"})
public String index()
{
return StringUtils.join("client ip: ", getClientIp());
}
String[] IP_HEADERS = {"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_CLIENT_IP", "HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_VIA", "REMOTE_ADDR"};
/**
* 獲取客戶端真實IP地址
*/
private String getClientIp()
{
for (String header : IP_HEADERS)
{
String ip = request.getHeader(header);
if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip))
{
// 處理多個IP的情況(逗號分隔)
log.info("##### ip header: {}", header);
String[] ips = ip.split(",");
return ips[0].trim();
}
}
log.info("##### request.getRemoteAddr");
return request.getRemoteAddr();
}
}為了方便運行,已經(jīng)將工程打包成docker鏡像,地址為:registry.cn-shanghai.aliyuncs.com/00fly/springboot-nginx:1.0.0
三、功能驗證
目錄結(jié)構(gòu)
├── conf.d │ └── web.conf ├── docker-compose.yml
1. 編排文件
docker-compose.yml
services:
nginx:
image: nginx:alpine
container_name: my-nginx
deploy:
resources:
limits:
cpus: '2.0'
memory: 10M
reservations:
cpus: '2.0'
memory: 10M
ports:
- 8080:80
links:
- web:web
restart: on-failure
volumes:
- ./conf.d/:/etc/nginx/conf.d/
logging:
driver: json-file
options:
max-size: 5m
max-file: '1'
web:
hostname: web
image: registry.cn-shanghai.aliyuncs.com/00fly/springboot-nginx:1.0.0
container_name: web
deploy:
resources:
limits:
cpus: '2.0'
memory: 200M
reservations:
cpus: '2.0'
memory: 200M
environment:
CONTEXT_PATH: /
#CONTEXT_PATH: /luck
restart: on-failure
logging:
driver: json-file
options:
max-size: 5m
max-file: '1'2. 代理配置
web.conf
server {
listen 80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://web:8080;
client_max_body_size 5m;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}3. nginx配置
首先,確保啟用了realip模塊
進(jìn)入nginx容器內(nèi)執(zhí)行nginx -V, 查看返回是否有--with-http_realip_module,如有說明當(dāng)前版本鏡像已經(jīng)啟用了realip模塊。
[root@00fly docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ef8e4b3d8269 nginx:alpine "/docker-entrypoint.…" 5 seconds ago Up 3 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp my-nginx 5830a2be7439 registry.cn-shanghai.aliyuncs.com/00fly/springboot-nginx:1.0.0 "java -Djava.securit…" 5 seconds ago Up 4 seconds 8080/tcp web [root@00fly docker]# docker exec -it my-nginx sh nginx -V nginx version: nginx/1.29.7 built by gcc 15.2.0 (Alpine 15.2.0) built with OpenSSL 3.5.5 27 Jan 2026 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/run/nginx.pid --lock-path=/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-perl_modules_path=/usr/lib/perl5/vendor_perl --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-Os -fstack-clash-protection -Wformat -Werror=format-security -fno-plt -g' --with-ld-opt='-Wl,--as-needed,-O1,--sort-common -Wl,-z,pack-relative-relocs'
其次,查看代理配置是否包含下面的配置
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;4. 功能驗證
使用下面的腳本啟動容器
docker-compose --compatibility up -d
訪問首頁: http:{ip}:8080
查看返回值: 如 client ip: 122.51.4.65
將此返回值與本地ip查詢網(wǎng)址值對比。

5. 源碼放送
http://118.178.86.130:8081/git/down?name=springboot-nginx
總結(jié)
到此這篇關(guān)于nginx代理模式下java獲取客戶端真實ip地址的文章就介紹到這了,更多相關(guān)java獲取客戶端真實ip地址內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring?security需求分析與基礎(chǔ)環(huán)境準(zhǔn)備教程
這篇文章主要為大家介紹了spring?security需求分析與基礎(chǔ)環(huán)境準(zhǔn)備教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
SpringBoot 對象轉(zhuǎn)換 MapStruct的實現(xiàn)小結(jié)
MapStruct是一個基于注解的Java對象映射工具,通過在編譯時生成映射代碼實現(xiàn)高效的對象轉(zhuǎn)換,下面就來詳細(xì)的介紹一下SpringBoot 對象轉(zhuǎn)換 MapStruct的實現(xiàn),感興趣的可以了解一下2026-02-02
Java中的notyfy()和notifyAll()的本質(zhì)區(qū)別
很多朋友對java中的notyfy()和notifyAll()的本質(zhì)區(qū)別不了解,今天小編抽空給大家整理一篇教程關(guān)于Java中的notyfy()和notifyAll()的本質(zhì)區(qū)別,需要的朋友參考下吧2017-02-02
Java WebSocket客戶端接收大量數(shù)據(jù)的三種方案
WebSocket是一種基于TCP協(xié)議的全雙工通信協(xié)議,它能夠在客戶端和服務(wù)器之間建立一個持久連接,實現(xiàn)實時的雙向數(shù)據(jù)傳輸,在實際應(yīng)用中,有時候我們需要處理大量的數(shù)據(jù),所以本文將介紹如何使用 Java WebSocket 客戶端接收大量數(shù)據(jù),并提供一些優(yōu)化方案2023-11-11
MyBatis代碼自動生成器Mybatis-Generator的使用詳解
本文詳細(xì)介紹如何在SpringBoot項目中使用MyBatis-Generator進(jìn)行代碼生成,包括配置文件的添加、POM依賴配置、運行配置等步驟,通過自動生成代碼,可以簡化MyBatis的繁瑣配置和SQL編寫,提高開發(fā)效率,注意要考慮MySQL版本兼容性,以及確保路徑配置正確2024-10-10

