青島鑫隆建設(shè)集團網(wǎng)站網(wǎng)絡(luò)推廣山東
上篇在本地測試調(diào)用Ip2Resigon解析行政區(qū)劃 Ip2Region的Java本地實現(xiàn)運行正常,但部署到測試環(huán)境,拋出數(shù)組越界(java.lang.ArrayIndexOutOfBoundsException)異常。
環(huán)境信息
ip2Resion是2.7版本,對應(yīng)文件后綴為 xdb。
一、代碼展示
調(diào)用解析關(guān)鍵代碼如下所示。
@Service
public class Ip2RegionService implements IIp2RegionService {/*** 功能:通過ip轉(zhuǎn)化行政區(qū)劃 并發(fā)使用,用整個 xdb 數(shù)據(jù)緩存創(chuàng)建的查詢對象可安全的用于并發(fā),* 把這個 searcher 對象做成全局對象去跨線程訪問。* @param ip* @return*/@Overridepublic Ip2RegionCommon getDistrictByIp(String ip) {logger.info("getDistrictByIp方法入?yún)?" + ip);String region = "未解析到位置信息";// 數(shù)據(jù)文件路徑String dbPath = this.getClass().getClassLoader().getResource("xdb/ip2region.xdb").getPath();logger.info("getDistrictByIp獲取的dbPath為:" + dbPath);long startTime = System.currentTimeMillis();try {byte[] cBuff = null;Searcher searcher;// 1、加載整個 xdb 到內(nèi)存。cBuff = Searcher.loadContentFromFile(dbPath);// 2、創(chuàng)建一個完全基于內(nèi)存的查詢對象。searcher = Searcher.newWithBuffer(cBuff);// 3、調(diào)用查詢方法region = searcher.search(ip);long endTime = System.currentTimeMillis();// 4、關(guān)閉資源 - 該 searcher 對象可以安全用于并發(fā),等整個服務(wù)關(guān)閉的時候再關(guān)閉 searcherlogger.info("getDistrictByIp解析出來的region為:" + region);// searcher.close();logger.info("getDistrictByIp方法執(zhí)行耗時:" + (endTime - startTime) + "ms");} catch (Exception e) {logger.info("getDistrictByIp 執(zhí)行出錯,錯誤信息為:%s",e.getMessage());logger.logException("getDistrictByIp 執(zhí)行出錯,錯誤信息為:%s", e);}return this.getReginResult(region);}/*** 功能:轉(zhuǎn)換結(jié)果* 數(shù)據(jù)格式: 國家|區(qū)域|省份|城市|ISP* 內(nèi)網(wǎng)IP格式: 0|0|0|內(nèi)網(wǎng)IP|內(nèi)網(wǎng)IP* @param region* @return*/public Ip2RegionCommon getReginResult(String region) {Ip2RegionCommon info = new Ip2RegionCommon();if(region.contains("|")) {String[] split = StringUtils.split(region, "|");info.setDistrictCountry(split[0]);info.setDistrictProvince(this.suppleDistrict(split[2]));info.setDistrictCity(split[3]);info.setDistrictIsp(split[4]);}return info;}/*** 功能:補全省份名稱* @param provinceName* @return*/private String suppleDistrict(String provinceName) {String province = "省份未知";switch(provinceName) {case "北京" :province = "北京市";break;case "天津" :province = "天津市";break;case "上海" :province = "上海市";break;case "重慶" :province = "重慶市";break;case "廣西" :province = "廣西壯族自治區(qū)";break;case "西藏" :province = "西藏自治區(qū)";break;case "寧夏" :province = "寧夏回族自治區(qū)";break;case "新疆" :province = "新疆維吾爾自治區(qū)";break;case "黑龍江" :province = "黑龍江省";break;case "內(nèi)蒙古" :province = "內(nèi)蒙古自治區(qū)";break;default :province = provinceName;}return province;}}
異常信息日志展示如下。
二、問題分析
從打印日志看數(shù)據(jù)xdb文件讀取成功,searcher對象創(chuàng)建成功,進入search方法里,在arraycopy時報錯。
猜想是Java啟動時給的內(nèi)存不足,加大內(nèi)存未見好使;
取到ip地址在本地單元測試執(zhí)行,順利解析,應(yīng)該不是ip地址的問題;
再次想會不會只是創(chuàng)建了searcher對象,沒有讀取到內(nèi)容呢?于是在網(wǎng)上繼續(xù)查找,終于看到碼云上有說少配置,詳細可見參考文檔。
maven resources 拷貝文件是默認會做 filter,會導(dǎo)致數(shù)據(jù)文件發(fā)生變化,導(dǎo)致文件不能被讀。
三、處理方案
明確原因后,在Java打包的pom文件中添加以下內(nèi)容。指定 nonFilteredFileExtension 格式為xdb,問題解決。
<plugins><plugin><artifactId>maven-resources-plugin</artifactId><configuration><nonFilteredFileExtensions><nonFilteredFileExtension>xdb</nonFilteredFileExtension></nonFilteredFileExtensions></configuration></plugin>
</plugins>
參考文檔
【1】https://gitee.com/596392912/mica/blob/master/mica-ip2region/README.md