How do I get the remote address of a client in servlet?
有什么办法可以使客户机获得服务器的原始IP地址?
我可以使用
我想知道客户端用来连接我的IP地址。 无论如何,我能得到吗?
尝试这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public static String getClientIpAddr(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(); } return ip; } |
我用过的最好的解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 | public String getIpAddr(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.getRemoteAddr(); } return ip; } |
由于这通常是部署问题,而不是应用程序问题,因此另一种方法是适当地配置应用程序容器。配置完成后,容器将负责检查适当的标头,并且您的应用程序继续使用
例如,在Tomcat中,您可以使用Remote IP Valve。我假设大多数应用程序服务器具有类似的功能。
容器还可以帮助您了解前端负载均衡器是否正在终止SSL连接,并通过HTTP将请求转发至应用服务器。当您的应用程序需要为其自身生成URL时,这一点很重要。
您无法以有意义的方式执行此操作。
代理可以添加也可以不添加代理标头,但是在许多情况下,无论如何这都是内部唯一的地址,因此对您而言毫无意义。无论如何,组织边缘的大多数代理都配置为尽可能少地揭示网络内部。
您打算将这些信息用于什么?
为什么不使用这样更优雅的解决方案?
1 2 3 4 5 6 7 8 9 10 | private static final List<String> IP_HEADERS = Arrays.asList("X-Forwarded-For","Proxy-Client-IP","WL-Proxy-Client-IP","HTTP_CLIENT_IP","HTTP_X_FORWARDED_FOR"); public static String getClientIpAddr(HttpServletRequest request) { return IP_HEADERS.stream() .map(request::getHeader) .filter(Objects::nonNull) .filter(ip -> !ip.isEmpty() && !ip.equalsIgnoreCase("unknown")) .findFirst() .orElseGet(request::getRemoteAddr); } |
重复删除您的代码!
如果使用代理或负载平衡器,则" x-forwarded-for"请求标头包含原始客户端IP。但我认为并非所有代理/ lb都添加了此标头。
下面是一些用于解析标头的Java代码:
http://www.codereye.com/2010/01/get-real-ip-from-request-in-java.html
如果此标头不存在,那么我将按照@Bozho的建议进行操作
为什么我认为我们应该首先尝试从标头'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /** * Try to get real ip from request: * <ul> * <li> try X-Forwarded-For </li> * <li> try remote address </li> * </ul> * * @param request request * @return real ip or"" */ private String tryGetRealIp(HttpServletRequest request) { // X-Forwarded-For: <client>, <proxy1>, <proxy2> // If a request goes through multiple proxies, the IP addresses of each successive proxy is listed. // This means, the right-most IP address is the IP address of the most recent proxy and // the left-most IP address is the IP address of the originating client. String forwards = request.getHeader("X-Forwarded-For"); if (StringUtils.isNotBlank(forwards)) { // The left-most IP must be client ip String ip = StringUtils.substringBefore(forwards,","); return ip; } else if (StringUtils.isNotBlank(request.getRemoteAddr())) { // this could be real client ip or last proxy ip which forwards the request return request.getRemoteAddr(); } return""; } |
1 2 3 4 5 6 7 | String ipAddress = request.getHeader("x-forwarded-for"); if (ipAddress == null) { ipAddress = request.getHeader("X_FORWARDED_FOR"); if (ipAddress == null){ ipAddress = request.getRemoteAddr(); } } |
1 2 | InetAddress inetAddress = InetAddress.getLocalHost(); String ip = inetAddress.getHostAddress(); |