JAVA与Jsp取本机ip地址的正确方法,ipv6有效

来源:互联网 发布:省市区数据库sql 编辑:程序博客网 时间:2024/05/17 08:28
//[转]JAVA取本机ip地址的正确方法,ipv6有效 //除普通环境,还能适用于多网卡的、Linux环境import java.net.Inet6Address;import java.net.InetAddress;import java.net.NetworkInterface;import java.util.Enumeration;public class Test {public static void main(String[] args) throws Exception {   Test t = new Test();   t.getLocalIP();}public void getLocalIP() throws Exception {   Enumeration e1 = (Enumeration) NetworkInterface.getNetworkInterfaces();   while (e1.hasMoreElements()) {    NetworkInterface ni = (NetworkInterface) e1.nextElement();    System.out.print(ni.getName());    System.out.print(": ");    Enumeration e2 = ni.getInetAddresses();    while (e2.hasMoreElements()) {     InetAddress ia = (InetAddress) e2.nextElement();     if (ia instanceof Inet6Address)      continue; // omit IPv6 address     System.out.print(ia.getHostAddress());     if (e2.hasMoreElements()) {      System.out.print(", ");     }    }    System.out.print("\n");   }}}



在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。 如果使用了反向代理软件,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问 时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问 ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过request.getRemoteAddr()的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。    于是可得出获得客户端真实IP地址的方法一:public String getRemortIP(HttpServletRequest request) {  if (request.getHeader("x-forwarded-for") == null) {   return request.getRemoteAddr();  }  return request.getHeader("x-forwarded-for"); } 可是当我访问  时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问 :2046/index.jsp 时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:X-Forwarded-For: unknown    于是可得出获得客户端真实IP地址的方法二: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;   }     可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串Ip值,究竟哪个才是真正的用户端的真实IP呢?    答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。    如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100用户真实IP为: 192.168.1.110 


try   {InetAddress[]   ia   =   InetAddress.getAllByName(InetAddress.getLocalHost().getHostName());for(int   i=0;i <ia.length;i++){System.out.print(ia[i].getHostAddress().toString());}}   catch   (UnknownHostException   ex)   {//   TODO   自动生成   catch   块ex.printStackTrace();}public   String[]   getIpAddress(String   hostname)   throws   SocketException,UnknownHostException   {String[]   get   =   null;InetAddress[]   inetAddress   =   null;if   (new   CommonConvert().isEmpty(hostname))   {hostname   =   "localhost ";}inetAddress   =   Inet4Address.getAllByName(hostname.toLowerCase());if   (inetAddress.length   >   0   &&   inetAddress   !=   null)   {get   =   new   String[inetAddress.length];for   (int   i   =   0;i <inetAddress.length;i++)   {get[i]   =   inetAddress[i].getHostAddress();}}return   get;}

使用request对象的以下三个方法可以得到相关的信息,不过如果中间有代理服务器的话,则不适用了。以下是API文档中的说明: String getRemoteAddr()           Returns the Internet Protocol (IP) address of the client or last proxy that sent the request.  String getRemoteHost()           Returns the fully qualified name of the client or the last proxy that sent the request.  int getRemotePort()           Returns the Internet Protocol (IP) source port of the client or last proxy that sent the request. 



原创粉丝点击