IPUtils.java 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package com.zsElectric.boot.common.util;
  2. import cn.hutool.core.util.StrUtil;
  3. import jakarta.annotation.PostConstruct;
  4. import jakarta.servlet.http.HttpServletRequest;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.lionsoul.ip2region.xdb.Searcher;
  7. import org.springframework.stereotype.Component;
  8. import java.io.FileNotFoundException;
  9. import java.io.InputStream;
  10. import java.net.InetAddress;
  11. import java.net.UnknownHostException;
  12. import java.nio.file.Files;
  13. import java.nio.file.Path;
  14. import java.nio.file.StandardCopyOption;
  15. /**
  16. * IP工具类
  17. * <p>
  18. * 获取客户端IP地址和IP地址对应的地理位置信息
  19. * <p>
  20. * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
  21. * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
  22. * </p>
  23. *
  24. * @author Ray
  25. * @since 2.10.0
  26. */
  27. @Slf4j
  28. @Component
  29. public class IPUtils {
  30. private static final String DB_PATH = "/data/ip2region.xdb";
  31. private static Searcher searcher;
  32. @PostConstruct
  33. public void init() {
  34. try {
  35. // 从类路径加载资源文件
  36. InputStream inputStream = getClass().getResourceAsStream(DB_PATH);
  37. if (inputStream == null) {
  38. throw new FileNotFoundException("Resource not found: " + DB_PATH);
  39. }
  40. // 将资源文件复制到临时文件
  41. Path tempDbPath = Files.createTempFile("ip2region", ".xdb");
  42. Files.copy(inputStream, tempDbPath, StandardCopyOption.REPLACE_EXISTING);
  43. // 使用临时文件初始化 Searcher 对象
  44. searcher = Searcher.newWithFileOnly(tempDbPath.toString());
  45. } catch (Exception e) {
  46. log.error("IpRegionUtil initialization ERROR, {}", e.getMessage());
  47. }
  48. }
  49. /**
  50. * 获取IP地址
  51. *
  52. * @param request HttpServletRequest对象
  53. * @return 客户端IP地址
  54. */
  55. public static String getIpAddr(HttpServletRequest request) {
  56. String ip = null;
  57. try {
  58. if (request == null) {
  59. return "";
  60. }
  61. ip = request.getHeader("x-forwarded-for");
  62. if (checkIp(ip)) {
  63. ip = request.getHeader("Proxy-Client-IP");
  64. }
  65. if (checkIp(ip)) {
  66. ip = request.getHeader("WL-Proxy-Client-IP");
  67. }
  68. if (checkIp(ip)) {
  69. ip = request.getHeader("HTTP_CLIENT_IP");
  70. }
  71. if (checkIp(ip)) {
  72. ip = request.getHeader("HTTP_X_FORWARDED_FOR");
  73. }
  74. if (checkIp(ip)) {
  75. ip = request.getRemoteAddr();
  76. if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
  77. // 根据网卡取本机配置的IP
  78. ip = getLocalAddr();
  79. }
  80. }
  81. } catch (Exception e) {
  82. log.error("IPUtils ERROR, {}", e.getMessage());
  83. }
  84. // 使用代理,则获取第一个IP地址
  85. if (StrUtil.isNotBlank(ip) && ip.indexOf(",") > 0) {
  86. ip = ip.substring(0, ip.indexOf(","));
  87. }
  88. return ip;
  89. }
  90. private static boolean checkIp(String ip) {
  91. String unknown = "unknown";
  92. return StrUtil.isEmpty(ip) || unknown.equalsIgnoreCase(ip);
  93. }
  94. /**
  95. * 获取本机的IP地址
  96. *
  97. * @return 本机IP地址
  98. */
  99. private static String getLocalAddr() {
  100. try {
  101. return InetAddress.getLocalHost().getHostAddress();
  102. } catch (UnknownHostException e) {
  103. log.error("InetAddress.getLocalHost()-error, {}", e.getMessage());
  104. }
  105. return null;
  106. }
  107. /**
  108. * 根据IP地址获取地理位置信息
  109. *
  110. * @param ip IP地址
  111. * @return 地理位置信息
  112. */
  113. public static String getRegion(String ip) {
  114. if (searcher == null) {
  115. log.error("Searcher is not initialized");
  116. return null;
  117. }
  118. try {
  119. return searcher.search(ip);
  120. } catch (Exception e) {
  121. log.error("IpRegionUtil ERROR, {}", e.getMessage());
  122. return null;
  123. }
  124. }
  125. }