jsp获取客户端ip地址

JSP里获取客户端IP,获户端十有八九你写的取客是 request.getRemoteAddr()。这行代码在本地测试时永远返回127.0.0.1,地址看着挺正常。获户端可一旦部署到生产环境,取客前面挂了Nginx或者Apache代理,地址这方法拿到的获户端就全是代理服务器的IP——清一色的127.0.0.1,或者内网网关地址。取客

我见过不少新手在这上面栽跟头。地址有个同事调了一下午,获户端最后发现所有用户日志里的取客IP都一样,还以为是地址数据库查询写错了。其实问题出在请求链路中间多了层转发。获户端

要拿到真实IP,取客得从HTTP头里找。地址代理服务器一般会把原始IP塞进 X-Forwarded-For 或 X-Real-IP 这两个请求头里。Nginx默认配置 proxy_set_header X-Real-IP $remote_addr;,Apache的mod_proxy也有类似设置。所以代码得改成先看请求头,再看 getRemoteAddr() 兜底。

写个工具方法大概长这样:

public String getClientIp(HttpServletRequest request) {  String ip = request.getHeader("X-Real-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.getRemoteAddr(); } return ip; } 

但这里有个坑——X-Forwarded-For 可能是逗号分隔的一串IP,比如 1.2.3.4, 10.0.0.1。这是因为每经过一层代理,代理服务器会把自己的IP追加到末尾。所以取的时候得拿第一个,那是客户端的真实地址。直接 split(",")[0] 再trim一下。

另一个坑是伪造问题。HTTP头是可以随便改的,用户拿curl直接 -H "X-Forwarded-For: 8.8.8.8" 就能骗过你的代码。如果IP只用来做展示、统计,问题不大。但你要是拿它做登录限制、防刷、风控,那就得小心了。最靠谱的办法是只信任离你最近的那层代理设置的头部,比如Nginx里用 $http_x_real_ip 覆盖掉用户传上来的值,后端再取就安全了。

还有种情况,你用了CDN,比如Cloudflare。它的请求头是 CF-Connecting-IP,得单独适配。不过一般CDN也会回源时把原始IP放进 X-Forwarded-For,所以通用方案通常够用。

再补一句,IPv6环境下 getRemoteAddr() 返回的是像 240e:390:xxxx 这样的长串,存数据库时VARCHAR别只给15位,至少50。我见过有人因为字段长度不够,IPv6地址被截断,查日志时怎么都对不上号。

最后给个建议:别每次请求都现写这堆判断逻辑,封装成一个静态方法放在公共类里,或者写个过滤器统一处理。代码整洁是一方面,更重要的是处理逻辑只维护一份,以后要加新的代理类型,改一处就行。

简单说,JSP取客户端IP的核心就三步:先看代理头,取第一个非unknown的值,最后用 getRemoteAddr() 兜底。至于安全性,那是另一层要考虑的事。