package com.fpi.system.utils;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import java.io.*;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author: kht
* @date: 2021/12/23
* @description:根据ip获取地理信息
*/
@Slf4j
public class AddressUtil {
/**
* 根据IP获取所在城市的名称(返回格式:中国|华东|浙江省|杭州市|电信)
*/
public static String getCityInfo(String ip) {
DbSearcher searcher = null;
try {
String dbPath = AddressUtil.class.getResource("/ip2region/ip2region.db").getPath();
File file = new File(dbPath);
if (!file.exists()) {
String tmpDir = System.getProperties().getProperty("java.io.tmpdir");
dbPath = tmpDir + "ip.db";
file = new File(dbPath);
FileUtils.copyInputStreamToFile(AddressUtil.class.getClassLoader().getResourceAsStream("classpath:ip2region/ip2region.db"), file);
}
int algorithm = DbSearcher.BTREE_ALGORITHM;
DbConfig config = new DbConfig();
searcher = new DbSearcher(config, dbPath);
Method method = null;
switch (algorithm) {
case DbSearcher.BTREE_ALGORITHM:
method = searcher.getClass().getMethod("btreeSearch", String.class);
break;
case DbSearcher.BINARY_ALGORITHM:
method = searcher.getClass().getMethod("binarySearch", String.class);
break;
case DbSearcher.MEMORY_ALGORITYM:
method = searcher.getClass().getMethod("memorySearch", String.class);
break;
default:break;
}
DataBlock dataBlock = null;
if (!Util.isIpAddress(ip)) {
log.error("Error: Invalid ip address");
}
dataBlock = (DataBlock) method.invoke(searcher, ip);
return dataBlock.getRegion();
} catch (Exception e) {
log.error("获取IP地址失败,{}", e.getMessage());
} finally {
if (searcher != null) {
try {
searcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* 根据IP获取所在城市的名称(返回格式:杭州)
*/
public static String getCityByIp(String ip) {
String city ="";
String jsonStr = "";
String strUrl = "http://apis.juhe.cn/ip/ipNew";
String srtVlaue = "ip="+ip+"&key=";
String requestTimeout="请求超时";
jsonStr = HttpGetPost.sendGet(strUrl,srtVlaue);
if(jsonStr.equals(requestTimeout)) {
return "获取城市名称失败";
}
JSONObject json = JSONObject.fromObject(jsonStr);
String resultcode = (String) json.get("resultcode");
String successCode="200";
String urban="市";
//接口請求成功
if(resultcode.equals(successCode)) {
JSONObject result = (JSONObject) json.get("result");
city = (String) result.get("City");
}else {
city = "所在城市获取失败";
}
if(city.contains(urban)) {
//只截取前两位汉字
city = city.substring(0, 2);
}
System.out.println("根据IP:"+ip+"获取城市名称为:"+city);
return city;
}
/**
* 根据城市名称获取该城市的天气状况(要求格式:杭州)
*/
public static Map<String,Object> getWeatherByCity(String city) {
Map<String,Object> hashmap = new HashMap<String, Object>(20,20);
String jsonStr = "";
String strUrl = "http://apis.juhe.cn/simpleWeather/query";
String srtVlaue = "city="+city+"&key=";
jsonStr = HttpGetPost.sendGet(strUrl,srtVlaue);
System.out.println(jsonStr);
JSONObject json = JSONObject.fromObject(jsonStr);
String reason = (String) json.get("reason");
String querySuccess="查询成功!";
if(reason.equals(querySuccess)) {
hashmap = JsonUtil.parseJsonstrMap(jsonStr);
}else {
hashmap.put("error_code", "获取"+city+"天气失败");
}
return hashmap;
}
/**
* 获取本机外网ip(万网)
**/
public static String getPublicIp() {
try {
//要获得html页面内容的地址(万网)
String path = "http://www.net.cn/static/customercare/yourip.asp";
// 创建url对象
URL url = new URL(path);
// 打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置url中文参数编码
conn.setRequestProperty("contentType", "GBK");
// 请求的时间
conn.setConnectTimeout(5 * 1000);
// 请求方式
conn.setRequestMethod("GET");
InputStream inStream = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(
inStream, "GBK"));
StringBuilder buffer = new StringBuilder();
String line;
// 读取获取到内容的最后一行,写入
while ((line = in.readLine()) != null) {
buffer.append(line);
}
List<String> ips = new ArrayList<>();
//用正则表达式提取String字符串中的IP地址
String regEx="((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)";
String str = buffer.toString();
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
while (m.find()) {
String result = m.group();
ips.add(result);
}
// 返回公网IP值
return ips.get(0);
} catch (Exception e) {
System.out.println("获取公网IP连接超时");
return "";
}
}
}