关于 ip 操作的几个实用函数
Posted sp42a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于 ip 操作的几个实用函数相关的知识,希望对你有一定的参考价值。
获取请求 ip
首先是获取客户端请求的 ip。
/**
* 获取请求 ip
*
* @return 客户端 ip
*/
public String getIp()
String ip = getHeader("x-forwarded-for");
if (!"unknown".equalsIgnoreCase(ip) && ip != null && ip.length() != 0)
int index = ip.indexOf(",");
if (index != -1)
ip = ip.substring(0, index);
return ip.startsWith("::ffff:") ? ip.replaceAll("::ffff:", "") : ip;
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = getHeader("Proxy-Client-IP");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = getHeader("WL-Proxy-Client-IP");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = getHeader("X-Real-Ip");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = getRemoteAddr();
return ip.startsWith("::ffff:") ? ip.replaceAll("::ffff:", "") : ip;
ip 拦截
其次是 ip 拦截。
// --------------IP 拦截----------------
static LRUCache<String, Boolean> cache = new LRUCache<>(20);
public static boolean isChinaMainlandIp(String ip)
Map<String, Object> map = Tools.getIpLocation(ip);
Object c = map.get("country");
if (c != null && "中国".equals(c.toString()))
Object r = map.get("region");
if (r != null && ("香港".equals(r.toString()) || "澳门".equals(r.toString()) || "台湾".equals(r.toString())))
return false;
return true;
else
return false;
public static boolean isChinaMainlandIp_Cache(String ip)
Boolean isChinaMainlandIp = cache.get(ip);
if (isChinaMainlandIp == null)
isChinaMainlandIp = isChinaMainlandIp(ip);
cache.put(ip, isChinaMainlandIp);
return isChinaMainlandIp;
public static boolean isChinaMainlandIp_Cache(HttpServletRequest req)
String ip = req instanceof MvcRequest ? ((MvcRequest) req).getIp() : new MvcRequest(req).getIp();
return isChinaMainlandIp_Cache(ip);
获取 ip 区域信息
当然也少不了如何获取 ip 区域信息的。这些都是免费的接口。
/**
* 淘宝 ip 查询,限制得很厉害,不推荐使用
*
* http://blog.zhukunqian.com/?p=1998 http://pv.sohu.com/cityjson?ie=utf-8
* https://gitee.com/meaktsui/ChinaIpSearch
*
* @param ip IPv4 地址
* @return 结果信息
*/
public static Map<String, Object> getIpLocation(String ip)
Map<String, Object> map = Get.api("https://ip.taobao.com/outGetIpInfo?ip=" + ip);
if (!map.containsKey(Get.ERR_MSG))
return map;
else
LOGGER.warning("接口返回不成功 " + map.get(Get.ERR_MSG));
return map;
/**
* ip 查询
*
* @param ipIPv4 地址
* @return 结果信息
*/
public static Map<String, Object> getIpLocation2(String ip)
Map<String, Object> map = Get.api("http://ip-api.com/json/" + ip + "?lang=zh-CN");
if (!map.containsKey(Get.ERR_MSG))
return map;
else
LOGGER.warning("接口返回不成功 " + map.get(Get.ERR_MSG));
return map;
Test
@Test
public void testGetIpLocation()
// assertEquals(0, Tools.getIpLocation("35.220.250.107").get("code"));
assertNotNull(Tools.getIpLocation2("35.220.250.107"));
@Test
public void testGetIpLocation2()
assertEquals("success", Tools.getIpLocation2("35.220.250.107").get("status"));
获取内网 ip 的三种方法
第一种方法,适合可以连接互联网的电脑。
/**
* 本地 ip 地址缓存
*/
public static String IP;
/**
* 获取本机 ip,带缓存的
*
* @return 本地 ip 地址
*/
public static String getLocalIp()
if (IP == null)
IP = getLocalHostLANAddress().getHostAddress();
return IP;
/**
* 获取本机局域网地址
*
* @return 本机局域网地址对象
*/
public static InetAddress getLocalHostLANAddress()
InetAddress candidateAddress = null;
try
// 遍历所有的网络接口
for (Enumeration<?> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();)
NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
// 在所有的接口下再遍历 IP
for (Enumeration<?> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();)
InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
if (!inetAddr.isLoopbackAddress()) // 排除 loopback 类型地址
if (inetAddr.isSiteLocalAddress())
return inetAddr;// 如果是 site-local 地址,就是它了
else if (candidateAddress == null)
candidateAddress = inetAddr;// site-local 类型的地址未被发现,先记录候选地址
if (candidateAddress != null)
candidateAddress = InetAddress.getLocalHost();// 如果没有发现 non-loopback 地址.只能用最次选的方案
catch (Exception e)
LOGGER.warning(e);
return candidateAddress;
不能连接外网?那么试试下面两个方法。
/**
* 如果 getLocalHostLANAddress() 放在不能连接公网的环境,那个方法就不适用了,可以使用这个方法
*
* @return 本地 ip 地址
*/
public static String getLocalIp2()
try (Socket socket = new Socket();)
socket.connect(new InetSocketAddress("baidu.com", 80));
return socket.getLocalAddress().getHostAddress();
catch (IOException e)
LOGGER.warning(e);
return null;
/**
* 第二种方法
*
* @return 本地 ip 地址
*/
public static String getLocalIp3()
try (DatagramSocket socket = new DatagramSocket())
socket.connect(InetAddress.getByName("114.114.114.114"), 10002);
return socket.getLocalAddress().getHostAddress();
catch (IOException e)
LOGGER.warning(e);
return null;
域名 whois 查询
最后附送域名 whois 查询,这跟 ip 没什么关系。
/**
* 域名是否已经注册
*
* @deprecated
* @param domain 域名
* @return true=可以注册
* @throws IOException 访问异常
*/
public static boolean isDomianRegisterAvailable(String domain) throws IOException
Map<String, String> map = Get.apiXML("http://panda.www.net.cn/cgi-bin/check.cgi?area_domain=" + domain);
if ("200".equals(map.get("returncode")))
if (map.get("original").startsWith("210"))
return true; // original=210 : Domain name is available 表示域名可以注册
else if (map.get("original").startsWith("211"))
return false;// original=211 : Domain name is not available 表示域名已经注册
else if (map.get("original").startsWith("212"))
throw new IOException("域名参数传输错误");
else
throw new IOException("未知错误! " + map);
else
throw new IOException("接口返回不成功 " + map);
/**
* 域名 whois 查询 https://www.nowapi.com/api/domain.whois
*
* @param domain 域名
* @return 域名详情
*/
public static Map<String, String> getWhois(String domain)
Map<String, String> map = Get.apiXML("http://api.k780.com/?app=domain.whois&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=xml&domain=" + domain);
if (!map.containsKey(Get.ERR_MSG))
return map;
else
LOGGER.warning("接口返回不成功 " + map.get(Get.ERR_MSG));
return map;
/**
* 判断IP是否内网
*
* @param ip
* @return true 表示为内网 ip
*/
public static boolean innerIP(String ip)
// 很简单的正则判断
return StrUtil.regTest(
"^(127\\\\.0\\\\.0\\\\.1)|(localhost)|(10\\\\.\\\\d1,3\\\\.\\\\d1,3\\\\.\\\\d1,3)|(172\\\\.((1[6-9])|(2\\\\d)|(3[01]))\\\\.\\\\d1,3\\\\.\\\\d1,3)|(192\\\\.168\\\\.\\\\d1,3\\\\.\\\\d1,3)$",
ip);
TEST
@Test
public void testGetWhois()
Map<String, String> whois = Tools.getWhois("ajaxjs.com");
System.out.println(whois);
assertNotNull(whois);
@Test
public void testInnerIP()
assertTrue(Tools.innerIP("192.168.1.100"));
以上是关于关于 ip 操作的几个实用函数的主要内容,如果未能解决你的问题,请参考以下文章