大致思路是客户端发起请求,我们首先根据请求获取到外网IP,然后再根据外网IP获取到用户所在城市,最后根据城市获取到天气信息
获取外网IP
万网获取外网IP地址: www.net.cn/static/cust…
/**
* @Description:获取客户端外网ip 此方法要接入互联网才行,内网不行
**/
public static String getPublicIp() {
try {
String path = "http://www.net.cn/static/customercare/yourip.asp";// 要获得html页面内容的地址(万网)
URL url = new URL(path);// 创建url对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 打开连接
conn.setRequestProperty("contentType", "GBK"); // 设置url中文参数编码
conn.setConnectTimeout(5 * 1000);// 请求的时间
conn.setRequestMethod("GET");// 请求方式
InputStream inStream = conn.getInputStream();
// readLesoSysXML(inStream);
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 "";
}
}
根据外网IP获取用户所在城市
首先你待需要一个ip2region.db文件,大家可以百度一下,我在这里整理了一份放在网盘上了,有需要的可以下载一下
链接:pan.baidu.com/s/1cR5VSzWE…提取码:asdn
这边是我另一个账号上的ip2region.db的 下载地址:download.csdn.net/download/as…
ip2region准确率99.9%的ip地址定位库,0.0x毫秒级查询,数据库文件大小只有1.5M,提供了java,php,c,python,nodejs,golang查询绑定和Binary,B树,内存三种查询算法
引入ip2region.db
maven依赖
<!--ip2region-->
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>1.7.2</version>
</dependency>
创建IPUtils工具类
@Log4j2
public class IPUtils {
/**
* 根据IP获取地址
*
* @return 国家|区域|省份|城市|ISP
*/
public static String getAddress(String ip) {
return getAddress(ip, DbSearcher.BTREE_ALGORITHM);
}
/**
* 根据IP获取地址
*
* @param ip
* @param algorithm 查询算法
* @return 国家|区域|省份|城市|ISP
* @see DbSearcher
* DbSearcher.BTREE_ALGORITHM; //B-tree
* DbSearcher.BINARY_ALGORITHM //Binary
* DbSearcher.MEMORY_ALGORITYM //Memory
*/
@SneakyThrows
public static String getAddress(String ip, int algorithm) {
if (!Util.isIpAddress(ip)) {
log.error("错误格式的ip地址: {}", ip);
return "";
}
String dbPath = IPUtils.class.getResource("/db/ip2region.db").getPath();
File file = new File(dbPath);
if (!file.exists()) {
log.error("地址库文件不存在");
return "";
}
DbSearcher searcher = new DbSearcher(new DbConfig(), dbPath);
DataBlock dataBlock;
switch (algorithm) {
case DbSearcher.BTREE_ALGORITHM:
dataBlock = searcher.btreeSearch(ip);
break;
case DbSearcher.BINARY_ALGORITHM:
dataBlock = searcher.binarySearch(ip);
break;
case DbSearcher.MEMORY_ALGORITYM:
dataBlock = searcher.memorySearch(ip);
break;
default:
log.error("未传入正确的查询算法");
return "";
}
searcher.close();
return dataBlock.getRegion();
}
根据城市获取天气信息
调用第三方天气接口获取天气信息,本文使用java自带工具类HttpUtils
@GetMapping("/weather")
@DecryptBody(encode = true) //响应加密
public Result getWeather(){
String publicIp = GetIPUtils.getPublicIp();//获取外网IP
if (StringUtils.isBlank(publicIp)) return ResultUtils.error("获取失败");
String cityInfo = IPUtils.getAddress(publicIp);//国家|区域|省份|城市|ISP
if (StringUtils.isBlank(cityInfo)) return ResultUtils.error("获取失败");
String[] split = cityInfo.split("\|");
String city = "";
for (String aSplit : split) if (aSplit.contains("市")) city = aSplit;//拿取市级名称
if (StringUtils.isBlank(city)) return ResultUtils.error("获取失败");
String weatherInformation = HttpUtil.get("http://portalweather.comsys.net.cn/weather03/api/weatherService/getDailyWeather?cityName=" + city);//调用天气接口
if (StringUtils.isBlank(weatherInformation)) return ResultUtils.error("获取失败");
Object o = ObjectMapperUtils.strToObj(weatherInformation,Object.class);
return ResultUtils.success("获取成功",o);
}
作者:Kiss
链接:https://juejin.cn/post/6990248455012614175
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。