Commit 40ce481e2e4a4b6b3ea240d3e32b1dd8a2cc087c

Authored by YunaiV
1 parent 4a2cb33c

ip:AreaUtils、IPUtils 优化

yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java
@@ -6,6 +6,7 @@ import cn.hutool.core.text.csv.CsvUtil; @@ -6,6 +6,7 @@ import cn.hutool.core.text.csv.CsvUtil;
6 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 6 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
7 import cn.iocoder.yudao.framework.ip.core.Area; 7 import cn.iocoder.yudao.framework.ip.core.Area;
8 import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum; 8 import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
  9 +import lombok.extern.slf4j.Slf4j;
9 10
10 import java.util.ArrayList; 11 import java.util.ArrayList;
11 import java.util.HashMap; 12 import java.util.HashMap;
@@ -17,19 +18,20 @@ import java.util.Map; @@ -17,19 +18,20 @@ import java.util.Map;
17 * 18 *
18 * @author 芋道源码 19 * @author 芋道源码
19 */ 20 */
  21 +@Slf4j
20 public class AreaUtils { 22 public class AreaUtils {
21 23
22 - private static Map<Integer, Area> areas;  
23 -  
24 - static {  
25 - // 懒加载,使用时初始化  
26 - init();  
27 - }  
28 -  
29 /** 24 /**
30 - * 初始化 25 + * 初始化 SEARCHER
31 */ 26 */
32 - private static synchronized void init() { 27 + @SuppressWarnings("InstantiationOfUtilityClass")
  28 + private final static AreaUtils INSTANCE = new AreaUtils();
  29 +
  30 +
  31 + private static Map<Integer, Area> areas;
  32 +
  33 + private AreaUtils() {
  34 + long now = System.currentTimeMillis();
33 areas = new HashMap<>(); 35 areas = new HashMap<>();
34 areas.put(Area.ID_GLOBAL, new Area(Area.ID_GLOBAL, "全球", 0, 36 areas.put(Area.ID_GLOBAL, new Area(Area.ID_GLOBAL, "全球", 0,
35 null, new ArrayList<>())); 37 null, new ArrayList<>()));
@@ -51,6 +53,7 @@ public class AreaUtils { @@ -51,6 +53,7 @@ public class AreaUtils {
51 area.setParent(parent); 53 area.setParent(parent);
52 parent.getChildren().add(area); 54 parent.getChildren().add(area);
53 } 55 }
  56 + log.info("启动加载 AreaUtils 成功,耗时 ({}) 毫秒", System.currentTimeMillis() - now);
54 } 57 }
55 58
56 /** 59 /**
yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/IPUtils.java
1 package cn.iocoder.yudao.framework.ip.core.utils; 1 package cn.iocoder.yudao.framework.ip.core.utils;
2 2
3 -import cn.iocoder.yudao.framework.common.exception.ServiceException; 3 +import cn.hutool.core.io.resource.ResourceUtil;
4 import cn.iocoder.yudao.framework.ip.core.Area; 4 import cn.iocoder.yudao.framework.ip.core.Area;
  5 +import lombok.SneakyThrows;
5 import lombok.extern.slf4j.Slf4j; 6 import lombok.extern.slf4j.Slf4j;
6 import org.lionsoul.ip2region.xdb.Searcher; 7 import org.lionsoul.ip2region.xdb.Searcher;
7 8
8 import java.io.IOException; 9 import java.io.IOException;
9 10
10 -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;  
11 -  
12 /** 11 /**
13 * IP 工具类 12 * IP 工具类
14 - * <p>  
15 - * 依赖于ip2region.xdb精简版,来源于<a href="https://gitee.com/zhijiantianya/ip2region"/>  
16 - * region精简为城市编码  
17 * 13 *
18 - * @author 芋道源码 14 + * IP 数据源来自 ip2region.xdb 精简版,基于 <a href="https://gitee.com/zhijiantianya/ip2region"/> 项目
  15 + *
  16 + * @author wanglhup
19 */ 17 */
20 @Slf4j 18 @Slf4j
21 public class IPUtils { 19 public class IPUtils {
22 20
23 /** 21 /**
24 - * 根据ip搜索  
25 - * 启动加载到内存中 22 + * 初始化 SEARCHER
26 */ 23 */
27 - private static Searcher SEARCHER; 24 + @SuppressWarnings("InstantiationOfUtilityClass")
  25 + private final static IPUtils INSTANCE = new IPUtils();
28 26
29 /** 27 /**
30 - * 初始化SEARCHER 28 + * IP 查询器,启动加载到内存中
31 */ 29 */
32 - private final static IPUtils INSTANCE = new IPUtils();  
33 - 30 + private static Searcher SEARCHER;
34 31
35 /** 32 /**
36 * 私有化构造 33 * 私有化构造
37 */ 34 */
38 private IPUtils() { 35 private IPUtils() {
39 - String dbPath = "ip2region.xdb";  
40 - dbPath = IPUtils.class.getClassLoader().getResource(dbPath).getPath();  
41 try { 36 try {
42 - SEARCHER = Searcher.newWithBuffer(Searcher.loadContentFromFile(dbPath)); 37 + long now = System.currentTimeMillis();
  38 + byte[] bytes = ResourceUtil.readBytes("ip2region.xdb");
  39 + SEARCHER = Searcher.newWithBuffer(bytes);
  40 + log.info("启动加载 IPUtils 成功,耗时 ({}) 毫秒", System.currentTimeMillis() - now);
43 } catch (IOException e) { 41 } catch (IOException e) {
44 - // 加载xdb文件异常,不影响启动  
45 - log.error("启动加载IP SEARCH异常", e);  
46 - SEARCHER = null; 42 + log.error("启动加载 IPUtils 失败", e);
47 } 43 }
48 } 44 }
49 45
50 -  
51 /** 46 /**
52 - * 查询IP对应的地区ID,格式应为127.0.0.1  
53 - * @param ip ip地址 47 + * 查询 IP 对应的地区编号
  48 + *
  49 + * @param ip IP 地址,格式为 127.0.0.1
54 * @return 地区id 50 * @return 地区id
55 */ 51 */
  52 + @SneakyThrows
56 public static Integer getAreaId(String ip) { 53 public static Integer getAreaId(String ip) {
57 - try {  
58 - return Integer.parseInt(SEARCHER.search(ip));  
59 - } catch (Exception e) {  
60 - throw new ServiceException(INTERNAL_SERVER_ERROR);  
61 - } 54 + return Integer.parseInt(SEARCHER.search(ip));
62 } 55 }
63 56
64 /** 57 /**
65 - * 查询IP对应的地区ID,格式参考{@link Searcher#checkIP(String)} 的返回  
66 - * @param ip ip地址  
67 - * @return 地区id 58 + * 查询 IP 对应的地区编号
  59 + *
  60 + * @param ip IP 地址的时间戳,格式参考{@link Searcher#checkIP(String)} 的返回
  61 + * @return 地区编号
68 */ 62 */
  63 + @SneakyThrows
69 public static Integer getAreaId(long ip) { 64 public static Integer getAreaId(long ip) {
70 - try {  
71 - return Integer.parseInt(SEARCHER.search(ip));  
72 - } catch (Exception e) {  
73 - throw new ServiceException(INTERNAL_SERVER_ERROR);  
74 - } 65 + return Integer.parseInt(SEARCHER.search(ip));
75 } 66 }
76 67
77 /** 68 /**
78 - * 查询IP对应的地区,格式应为127.0.0.1  
79 - * @param ip ip地址 69 + * 查询 IP 对应的地区
  70 + *
  71 + * @param ip IP 地址,格式为 127.0.0.1
80 * @return 地区 72 * @return 地区
81 */ 73 */
82 public static Area getArea(String ip) { 74 public static Area getArea(String ip) {
@@ -84,8 +76,9 @@ public class IPUtils { @@ -84,8 +76,9 @@ public class IPUtils {
84 } 76 }
85 77
86 /** 78 /**
87 - * 查询IP对应的地区,格式参考{@link Searcher#checkIP(String)} 的返回  
88 - * @param ip ip地址 79 + * 查询 IP 对应的地区
  80 + *
  81 + * @param ip IP 地址的时间戳,格式参考{@link Searcher#checkIP(String)} 的返回
89 * @return 地区 82 * @return 地区
90 */ 83 */
91 public static Area getArea(long ip) { 84 public static Area getArea(long ip) {
yudao-framework/yudao-spring-boot-starter-biz-ip/src/test/java/cn/iocoder/yudao/framework/ip/core/utils/IPUtilsTest.java
@@ -9,47 +9,39 @@ import static org.junit.jupiter.api.Assertions.assertEquals; @@ -9,47 +9,39 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
9 9
10 /** 10 /**
11 * {@link IPUtils} 的单元测试 11 * {@link IPUtils} 的单元测试
  12 + *
  13 + * @author wanglhup
12 */ 14 */
13 -class IPUtilsTest { 15 +public class IPUtilsTest {
14 16
15 @Test 17 @Test
16 - void getAreaId() { 18 + public void testGetAreaId_string() {
17 // 120.202.4.0|120.202.4.255|420600 19 // 120.202.4.0|120.202.4.255|420600
18 Integer areaId = IPUtils.getAreaId("120.202.4.50"); 20 Integer areaId = IPUtils.getAreaId("120.202.4.50");
19 assertEquals(420600, areaId); 21 assertEquals(420600, areaId);
20 } 22 }
21 23
22 @Test 24 @Test
23 - void testGetAreaId() { 25 + public void testGetAreaId_long() throws Exception {
24 // 120.203.123.0|120.203.133.255|360900 26 // 120.203.123.0|120.203.133.255|360900
25 - long ip = 0L;  
26 - try {  
27 - ip = Searcher.checkIP("120.203.123.250");  
28 - } catch (Exception e) {  
29 - // ignore  
30 - } 27 + long ip = Searcher.checkIP("120.203.123.250");
31 Integer areaId = IPUtils.getAreaId(ip); 28 Integer areaId = IPUtils.getAreaId(ip);
32 assertEquals(360900, areaId); 29 assertEquals(360900, areaId);
33 } 30 }
34 31
35 @Test 32 @Test
36 - void getArea() { 33 + public void testGetArea_string() {
37 // 120.202.4.0|120.202.4.255|420600 34 // 120.202.4.0|120.202.4.255|420600
38 Area area = IPUtils.getArea("120.202.4.50"); 35 Area area = IPUtils.getArea("120.202.4.50");
39 assertEquals("襄阳市", area.getName()); 36 assertEquals("襄阳市", area.getName());
40 } 37 }
41 38
42 @Test 39 @Test
43 - void testGetArea() { 40 + public void testGetArea_long() throws Exception {
44 // 120.203.123.0|120.203.133.255|360900 41 // 120.203.123.0|120.203.133.255|360900
45 - long ip = 0L;  
46 - try {  
47 - ip = Searcher.checkIP("120.203.123.252");  
48 - } catch (Exception e) {  
49 - // ignore  
50 - } 42 + long ip = Searcher.checkIP("120.203.123.252");
51 Area area = IPUtils.getArea(ip); 43 Area area = IPUtils.getArea(ip);
52 assertEquals("宜春市", area.getName()); 44 assertEquals("宜春市", area.getName());
53 -  
54 } 45 }
55 -}  
56 \ No newline at end of file 46 \ No newline at end of file
  47 +
  48 +}