关于 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\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3})|(172\\\\.((1[6-9])|(2\\\\d)|(3[01]))\\\\.\\\\d{1,3}\\\\.\\\\d{1,3})|(192\\\\.168\\\\.\\\\d{1,3}\\\\.\\\\d{1,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 操作的几个实用函数的主要内容,如果未能解决你的问题,请参考以下文章