IpUtil.java 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. package jnpf.util;
  2. import com.alibaba.fastjson.JSONObject;
  3. import jakarta.servlet.http.HttpServletRequest;
  4. import lombok.extern.slf4j.Slf4j;
  5. import java.io.ByteArrayOutputStream;
  6. import java.io.InputStream;
  7. import java.net.HttpURLConnection;
  8. import java.net.URL;
  9. import java.util.ArrayList;
  10. import java.util.HashSet;
  11. import java.util.List;
  12. import java.util.Set;
  13. import java.util.concurrent.Callable;
  14. import java.util.concurrent.Future;
  15. import java.util.concurrent.TimeUnit;
  16. import java.util.concurrent.TimeoutException;
  17. import java.util.regex.Matcher;
  18. import java.util.regex.Pattern;
  19. /**
  20. * @author JNPF开发平台组
  21. * @version V3.1.0
  22. * @copyright 引迈信息技术有限公司
  23. * @date 2021/3/16 10:51
  24. */
  25. @Slf4j
  26. public class IpUtil {
  27. /**
  28. * 检测ip信息的网站
  29. */
  30. private final static String IP_URL = "https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query={ip}&resource_id=6006";
  31. /**
  32. * IP的正则
  33. */
  34. private static Pattern pattern = Pattern
  35. .compile("(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})\\."
  36. + "(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})\\."
  37. + "(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})\\."
  38. + "(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})");
  39. /**
  40. * 内网IP
  41. *
  42. * @return
  43. */
  44. private static List<Pattern> ipFilterRegexList = new ArrayList<>();
  45. static {
  46. Set<String> ipFilter = new HashSet<String>();
  47. ipFilter.add("^10\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[0-9])"
  48. + "\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[0-9])" + "\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[0-9])$");
  49. // B类地址范围: 172.16.0.0---172.31.255.255
  50. ipFilter.add("^172\\.(1[6789]|2[0-9]|3[01])\\" + ".(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[0-9])\\"
  51. + ".(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[0-9])$");
  52. // C类地址范围: 192.168.0.0---192.168.255.255
  53. ipFilter.add("^192\\.168\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[0-9])\\"
  54. + ".(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[0-9])$");
  55. ipFilter.add("127.0.0.1");
  56. ipFilter.add("0.0.0.0");
  57. ipFilter.add("localhost");
  58. for (String tmp : ipFilter) {
  59. ipFilterRegexList.add(Pattern.compile(tmp));
  60. }
  61. }
  62. public static String getIpAddr() {
  63. HttpServletRequest request = ServletUtil.getRequest();
  64. if(request == null){
  65. //任务调度调用数据接口, 无法获取IP
  66. return "127.0.0.1";
  67. }
  68. String xIp = request.getHeader("X-Real-IP");
  69. String xFor = request.getHeader("X-Forwarded-For");
  70. if (StringUtil.isNotEmpty(xFor) && !"unKnown".equalsIgnoreCase(xFor)) {
  71. int index = xFor.indexOf(",");
  72. if (index != -1) {
  73. xFor = xFor.substring(0, index);
  74. }
  75. }else{
  76. xFor = xIp;
  77. }
  78. if (StringUtil.isBlank(xFor) || "unknown".equalsIgnoreCase(xFor)) {
  79. xFor = request.getHeader("Proxy-Client-IP");
  80. }
  81. if (StringUtil.isBlank(xFor) || "unknown".equalsIgnoreCase(xFor)) {
  82. xFor = request.getHeader("WL-Proxy-Client-IP");
  83. }
  84. if (StringUtil.isBlank(xFor) || "unknown".equalsIgnoreCase(xFor)) {
  85. xFor = request.getHeader("HTTP_CLIENT_IP");
  86. }
  87. if (StringUtil.isBlank(xFor) || "unknown".equalsIgnoreCase(xFor)) {
  88. xFor = request.getHeader("HTTP_X_FORWARDED_FOR");
  89. }
  90. if (StringUtil.isBlank(xFor) || "unknown".equalsIgnoreCase(xFor)) {
  91. xFor = request.getRemoteAddr();
  92. }
  93. return "0:0:0:0:0:0:0:1".equals(xFor) ? "127.0.0.1" : xFor;
  94. }
  95. /**
  96. * 检查IP是否合法
  97. *
  98. * @param ip
  99. * @return
  100. */
  101. public static boolean isValid(String ip) {
  102. Matcher m = pattern.matcher(ip);
  103. return m.matches();
  104. }
  105. /**
  106. * 获取ip信息
  107. */
  108. private static JSONObject getIpInfo(String ip) {
  109. JSONObject data = null;
  110. if (!ipIsInner(ip)) {
  111. long begin = System.currentTimeMillis();
  112. try {
  113. String ipUrl = IP_URL.replace("{ip}", ip);
  114. URL url = new URL(ipUrl);
  115. HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
  116. httpUrlConnection.setRequestMethod("GET");
  117. httpUrlConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
  118. httpUrlConnection.setDoInput(true);
  119. httpUrlConnection.setDoOutput(true);
  120. httpUrlConnection.setReadTimeout(5000);
  121. InputStream inputStream = httpUrlConnection.getInputStream();
  122. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  123. byte[] b = new byte[1024];
  124. int len = 0;
  125. while (true) {
  126. len = inputStream.read(b);
  127. if (len == -1) {
  128. break;
  129. }
  130. byteArrayOutputStream.write(b, 0, len);
  131. }
  132. long end = System.currentTimeMillis() - begin;
  133. byte[] lens = byteArrayOutputStream.toByteArray();
  134. String result = new String(lens, "GBK");
  135. data = JSONObject.parseObject(result);
  136. if (null == data) {
  137. return data;
  138. }
  139. data = JSONObject.parseObject(data.getJSONArray("data").get(0).toString());
  140. } catch (Exception e) {
  141. log.error("ip信息获取失败,请检查ip接口工具IPUtil。");
  142. }
  143. }
  144. return data;
  145. }
  146. /**
  147. * 获取ip所在的城市和宽带属于哪一家
  148. */
  149. public static String getIpCity(String ip) {
  150. if ("localhost".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
  151. ip = "127.0.0.1";
  152. }
  153. String region = Ip2RegionUtil.getIp2RegionStr(ip);
  154. if(StringUtil.isBlank(region)){
  155. region = getIpCityByInternet(ip);
  156. }
  157. return region;
  158. }
  159. /**
  160. * 获取ip所在的城市和宽带属于哪一家
  161. */
  162. public static String getIpCityByInternet(String ip) {
  163. if ("127.0.0.1".equals(ip) || "localhost".equals(ip)) {
  164. return "本地连接";
  165. }
  166. String ipInfo = null;
  167. if (ip != null) {
  168. JSONObject[] data = {null};
  169. Callable task = new Callable<JSONObject>() {
  170. @Override
  171. public JSONObject call() throws Exception {
  172. data[0] = getIpInfo(ip);
  173. return data[0];
  174. }
  175. };
  176. Future<String> future = ThreadPoolExecutorUtil.getExecutor().submit(task);
  177. try {
  178. //设置超时时间
  179. future.get(5, TimeUnit.SECONDS);
  180. } catch (TimeoutException e) {
  181. log.error("ip信息获取超时");
  182. } catch (Exception e) {
  183. log.error("ip信息获取错误:" + e.getMessage());
  184. }
  185. if (null == data[0]) {
  186. return "本地局域网";
  187. }
  188. ipInfo = data[0].getString("location");
  189. return ipInfo;
  190. }
  191. return ipInfo;
  192. }
  193. /**
  194. * 判断IP是否内网IP
  195. * @Title: ipIsInner
  196. * @param ip
  197. * @return: boolean
  198. */
  199. public static boolean ipIsInner(String ip) {
  200. boolean isInnerIp = false;
  201. for (Pattern tmp : ipFilterRegexList) {
  202. Matcher matcher = tmp.matcher(ip);
  203. if (matcher.find()) {
  204. isInnerIp = true;
  205. break;
  206. }
  207. }
  208. return isInnerIp;
  209. }
  210. }