一般的话,在 Servlet 中会先从 HTTP 请求头中获取,这是因为 Servlet 容器并不一定是真正暴露在 Internet 上的,而是通过 Web 服务器,甚至是负载均衡设备之后的,一个客户端的请求过来,经过了好几次的反向代理,如果直接使用 HttpServletRequest 的 getRemoteAddr() 获取的将是位于 Servlet 上一层代理服务器的 IP 地址,因此这种方式在生产环境中是不可靠的。
一般通过反向代理服务器的客户端请求,代理服务器都会将客户端源 IP 地址附加在原始的 HTTP 请求头上,非标准协议的代理源 IP 地址请求头有 X-Forwarded-For、X-Real-Ip 等,可以直接依据优先级从这些 HTTP 头获取数据,如果实现在获取不到的话,再从 HttpServletRequest 的 getRemoteAddr() 方法中获取。
参考代码如下:
/**
* 获得用户远程地址
*/
private String getRemoteAddr(HttpServletRequest request) {
String remoteAddr = request.getHeader("X-Real-IP");
if (StringUtils.isEmpty(remoteAddr)) {
remoteAddr = request.getHeader("X-Forwarded-For");
} else if (StringUtils.isEmpty(remoteAddr)) {
remoteAddr = request.getHeader("Proxy-Client-IP");
} else if (StringUtils.isEmpty(remoteAddr)) {
remoteAddr = request.getHeader("WL-Proxy-Client-IP");
}
return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
}
http://www.oschina.net/question/819166_124476
http://blog.csdn.net/sgx425021234/article/details/19043459