springboot項目中集成ip2region遇到的問題及解決辦法

1. 問題描述

在springboot項目中集成ip2region包,一開始參考了《崛起於Springboot2.X之集成ip2region(31) 》文章,運行測試都沒有問題,在此感謝作者的傾情奉獻。
但項目打成可執行的jar包後再運行,卻顯示找不到ip2region.db,經調試後發現

String dbPath = IpUtil.class.getResource("/ip2region/ip2region.db").getPath();

返回的路徑如下:

file:/D:/ws_java/esl/yunque-fs/target/demo2-0.0.3-SNAPSHOT.jar!/BOOT-INF/classes!/ip2region/ip2region.db

這個路徑很顯然無法被io讀取,所以造成了無法找到資源文件的錯誤。

2. 解決辦法

雖然絕對路徑無法使用,但仍然可以獲取到文件內容,代碼如下:

IpUtil.class.getClassLoader().getResourceAsStream("classpath:ip2region/ip2region.db")

那麼就可以把文件內容存儲到一個臨時文件中,這樣就可以直接使用新的臨時文件了。
具體代碼如下:

String dbPath = IpUtil.class.getResource("/ip2region/ip2region.db").getPath();
            System.out.println(dbPath);

            File file = new File(dbPath);
            if (file.exists() == false) {

                String tmpDir = System.getProperties().getProperty("java.io.tmpdir");
                dbPath = tmpDir + "ip.db";
                System.out.println(dbPath);
                file = new File(dbPath);
                FileUtils.copyInputStreamToFile(IpUtil.class.getClassLoader().getResourceAsStream("classpath:ip2region/ip2region.db"), file);

            }

在windows上臨時目錄如下:

C:\Users\ADMINI~1\AppData\Local\Temp\ip.db

這樣就可以解決找不到資源文件的問題了。

3. 完整代碼

public class IpUtil {
    public static String getCityInfo(String ip){

        try {
            //db

            String dbPath = IpUtil.class.getResource("/ip2region/ip2region.db").getPath();
            System.out.println(dbPath);

            File file = new File(dbPath);
            if (file.exists() == false) {

                String tmpDir = System.getProperties().getProperty("java.io.tmpdir");
                dbPath = tmpDir + "ip.db";
                System.out.println(dbPath);
                file = new File(dbPath);
                FileUtils.copyInputStreamToFile(IpUtil.class.getClassLoader().getResourceAsStream("classpath:ip2region/ip2region.db"), file);

            }

            //查詢算法
            int algorithm = DbSearcher.BTREE_ALGORITHM; //B-tree
            //DbSearcher.BINARY_ALGORITHM //Binary
            //DbSearcher.MEMORY_ALGORITYM //Memory
            try {
                DbConfig config = new DbConfig();
                DbSearcher searcher = new DbSearcher(config, dbPath);

                //define the method
                Method method = null;
                switch (algorithm) {
                    case DbSearcher.BTREE_ALGORITHM:
                        method = searcher.getClass().getMethod("btreeSearch", String.class);
                        break;
                    case DbSearcher.BINARY_ALGORITHM:
                        method = searcher.getClass().getMethod("binarySearch", String.class);
                        break;
                    case DbSearcher.MEMORY_ALGORITYM:
                        method = searcher.getClass().getMethod("memorySearch", String.class);
                        break;
                }

                DataBlock dataBlock = null;
                if (Util.isIpAddress(ip) == false) {
                    System.out.println("Error: Invalid ip address");
                }

                dataBlock = (DataBlock) method.invoke(searcher, ip);

                return dataBlock.getRegion();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章