package com.xxx.app.service.impl;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.pisen.yunma2.server.service.IpInfoService;
import com.pisen.yunma2.server.vo.IPInfo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author: fanxian
* @Date: 2024/10/22 15:13
**/
@Slf4j
@Service
public class IpInfoServiceImpl implements IpInfoService {
@Override
public IPInfo ipInfo(String ip) {
IPInfo ipInfo = new IPInfo(ip);
CompletableFuture.anyOf(
CompletableFuture.supplyAsync(()->fetchCountryCode(StrUtil.format("https://ipapi.com/ip_api.php?ip={}", ip), e->extractField(e, "country_code")))
.thenAccept(cCode -> ipInfo.setCountryCode(cCode)),
CompletableFuture.supplyAsync(()->fetchCountryCode(StrUtil.format("https://webapi-pc.meitu.com/common/ip_location?ip={}", ip), e->extractField(e, "nation_code")))
.thenAccept(cCode -> ipInfo.setCountryCode(cCode)),
CompletableFuture.supplyAsync(()->fetchCountryCode(StrUtil.format("https://ip-api.io/json/{}", ip), e->extractField(e, "country_code")))
.thenAccept(cCode -> ipInfo.setCountryCode(cCode)),
CompletableFuture.supplyAsync(()->fetchCountryCode(StrUtil.format("https://api.ipapi.is/?ip={}", ip), e->extractField(e, "country_code")))
.thenAccept(cCode -> ipInfo.setCountryCode(cCode))
).join();
return ipInfo;
}
private static Integer TIMEOUT = 1000;
public String fetchCountryCode(String url, Function<String,String> extractField) {
try {
log.info("fetching {}", url);
String resStr = HttpUtil.get(url, TIMEOUT);
String countryCode = extractField.apply(resStr);
Assert.notBlank(countryCode);
log.info("resp {} country code: {}", url, countryCode);
return countryCode.toUpperCase();
}catch (Exception e){
log.error("failed url: {}, error: {}", url, e.getMessage());
ThreadUtil.sleep(TIMEOUT+300, TimeUnit.MILLISECONDS); // 停一下,让其他请求成功返回
return null;
}
}
private static @Nullable String extractField(String resStr, String fieldName) {
String regex = "\""+fieldName+"\":\\s*\"([^\"]*)\"";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(resStr);
if (matcher.find()) {
String nationCode = matcher.group(1);
System.out.println("extract field... " + fieldName +": " + nationCode);
return nationCode;
} else {
System.out.println(fieldName +" not found.");
return null;
}
}
public static void main(String[] args) throws IOException {
// String ip = "172.66.43.8"; // not china
String ip = "121.8.215.106"; // china
IpInfoServiceImpl ipInfoService = new IpInfoServiceImpl();
IPInfo ipInfo = ipInfoService.ipInfo(ip);
System.out.println("--->ipInfo: " + JSONUtil.toJsonStr(ipInfo));
}
}
CompletableFuture并发获取IP的country_code
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。