【寫在前面】
編撰這篇文章還得從之前做安全業(yè)務(wù)需求說起,我們都知道安全攻擊都是在某臺客戶機上執(zhí)行某些惡意操作(sql注入,DoS/DDoS攻擊),致使服務(wù)端響應(yīng)異常崩潰亦或響應(yīng)數(shù)據(jù)被篡改,那么怎么去阻止這些東西呢?
首先我想到的是對訪問的web端做一個IP的校驗(好比阿里云服務(wù)器的安全組設(shè)置),建立一些白名單,這樣能在很大程度上做到一個限制,其實在服務(wù)端也應(yīng)該要開啟防火墻、設(shè)置權(quán)限等。那么我們首先得知道客戶端的IP是多少。接下來此文重點介紹如何獲取。
1、如何獲取客戶端訪問IP
其實獲取IP是最簡單的,因為只要有請求的話,都會存放在session里面的,只要通過下面這句話就可以拿到你所需要的IP,但是如何知道別人訪問你的服務(wù)器呢,這個時候就需要您自己去寫一個監(jiān)聽事件listen;
獲取IP方式如下代碼即可:
HttpSession session = request.getSession(false);
if (session == null) {
session = request.getSession();
System.out.println("session:" + session + "創(chuàng)建成功");
session.setAttribute("ip", request.getRemoteAddr());
System.out.println("----訪問的IP是:"+request.getRemoteAddr()+"----");
}
控制臺輸出:
2、如何通過IP獲取歸屬地(離線+在線)
通過上面的方式拿到了IP地址,那么我想知道是哪些地方的人訪問了我們的系統(tǒng)的話這就需要后臺去進行查詢了,這才是這篇文章的核心:
2.1 離線模式
主要是通過自己本地的離線庫來實現(xiàn)查找的,有個弊端就是需要不斷的更新。
第一步:下載離線包ip2region.xdb
首先下載一個離線的IP歸屬映射包ip2region.xdb,沒有的可以去我的百度云盤上下載
下載地址如下:
鏈接:https://pan.baidu.com/s/1l_Gfhl0TVPYXvpK9QSiXyw
提取碼:hdd6
第二步:引入離線包
將我們的離線包放在resources目錄下,如下圖所示:
Maven引入
打開項目中的pom.xml文件,將下面的代碼復(fù)制到里面去(如果有則忽略):
<!-- ip2region -->
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5</version>
</dependency>
開始引入時候可能會報紅,需要你自己去更新一下maven庫
沒有報紅表示本地引入成功。
Pom.xml引入靜態(tài)打包(特別關(guān)鍵,不然會報錯)
[Xxx/ip2region.xdb] cannot be opened because it does not exist
<resource>
<directory>src/main/resources</directory>
<includes>
<include>jdbc.properties</include>
<include>*.xml</include>
<include>ipdb/*.xdb</include>
</includes>
</resource>
主要是在構(gòu)建的時候我們java會變成class文件進行編譯,一些靜態(tài)資源需要自己手動去加才能打到j(luò)ar包里面去。
第三步:代碼實現(xiàn)
控制臺效果如下所示(國內(nèi)國外的都有):
核心實現(xiàn)代碼(記得要引入一些依賴包喲):
String dbPath = "/ipdb/ip2region.xdb";
try {
InputStream inputStream = new ClassPathResource(dbPath).getInputStream();
byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);
// 創(chuàng)建一個完全基于內(nèi)存的查詢對象
searcher = Searcher.newWithBuffer(dbBinStr);
} catch (Exception e) {
System.out.printf("failed to create content cached searcher: %s\n", e);
}
//把ip2r
String address = "";
try {
address = searcher.search("66.249.79.193");
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("=== 訪問者的地址為:"+address+" === ");
到這里我們就只要維護好那個離線包文件就可以,定時更新一下。
2.2 在線模式
主要通過別人或者官網(wǎng)提供的API接口去實現(xiàn)查詢的功能,有個弊端就是特別依賴別人的服務(wù)器,萬一別人服務(wù)器掛了就訪問不了了。
具體實現(xiàn)效果和2.1離線模式介紹的一樣
主要實現(xiàn)我封裝到一個java類里面,寫了一些特定的方法;
如下所示:
public static String getAddress(String ip) {
try {
URL realUrl = new URL("http://whois.pconline.com.cn/ipJson.jsp?ip=" + ip + "&json=true");
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
conn.setRequestMethod("GET");
conn.setUseCaches(false);
conn.setReadTimeout(6000);
conn.setConnectTimeout(6000);
conn.setInstanceFollowRedirects(false);
int code = conn.getResponseCode();
StringBuilder sb = new StringBuilder();
String ipaddr = "";
if (code == 200) {
InputStream in = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
ipaddr = ip + "=" + sb.substring(sb.indexOf("addr") + 7, sb.indexOf("regionNames") - 3);
}
return ipaddr;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
調(diào)用地方如下所示:
String address = IpAddressUtils.getAddress("66.249.79.193");
System.out.println("=== (在線)訪問者的地址為:"+address+" === ");
3、推薦方式,先離線后在線
【重要】其實我們可以結(jié)合兩個使用一起,先采用離線,如果發(fā)現(xiàn)為null的話則調(diào)用在線查詢的方式。這樣在一定的程度上能夠保證數(shù)據(jù)的完整性,都有不足的話就互補一下;如下所示邏輯:文章來源:http://www.zghlxwxcb.cn/news/detail-423939.html
System.out.println("--- (在線+離線)訪問者的IP為:66.249.79.193 --- ");
//================離線模式獲取=start====================//
String dbPath = "/ipdb/ip2region.xdb";
try {
InputStream inputStream = new ClassPathResource(dbPath).getInputStream();
byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);
// 創(chuàng)建一個完全基于內(nèi)存的查詢對象
searcher = Searcher.newWithBuffer(dbBinStr);
} catch (Exception e) {
System.out.printf("failed to create content cached searcher: %s\n", e);
}
//把ip2r
String address = "";
try {
address = searcher.search("221.231.220.212");
} catch (Exception e) {
throw new RuntimeException(e);
}
// String address = IpAddressUtils.getCityInfo("66.249.79.193");
System.out.println("=== (離線)訪問者的地址為:"+address+" === ");
//================離線模式獲取=end====================//
//======================在線模式獲取 start========================//
if("".equals(address)){
address = IpAddressUtils.getAddress("66.249.79.193");
System.out.println("=== (在線)訪問者的地址為:"+address+" === ");
}
//======================在線模式獲取 end========================//
4、彩蛋
如果覺得這篇文章對您有幫助的話,想支持博主的可以上皇榜看看喲,皇榜點擊此處進入文章來源地址http://www.zghlxwxcb.cn/news/detail-423939.html
到了這里,關(guān)于【獲取IP歸屬地】Java如何實現(xiàn)通過IP獲取IP歸屬地 [離線+在線](附代碼,2023年親測有效)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!