java根据ip地址获取用户地理位置
标签: ip解析 根据ip获取地理信息 ip解析地理位置
版权
功能需求
工作项目需要,根据用户向服务器请求的ip地址获取用户所在的地理位置。
具体代码
话不多说,直接上代码(作为一个负责任的程序员,我把import内容都贴贴出来了):
/**
- FileName: AddressUtils
- Author: Administrator
- Date: 2019-04-18 14:36
- Description: 通过ip地址获取访问地区
- History:
- 作者姓名:wxz 修改时间: 版本号: 描述:
*/
import org.springframework.boot.configurationprocessor.json.JSONObject;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
/**
-
根据IP地址获取详细的地域信息
-
淘宝API : http://ip.taobao.com/service/getIpInfo.php?ip=218.192.3.42
-
新浪API : http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=218.192.3.42
/
public class AddressUtils {
/*- @param content 请求的参数 格式为:ip=""
- @return
- @throws UnsupportedEncodingException
- @param//encoding 服务器端请求编码。如GBK,UTF-8等
*/
public static String getAddresses(String content, String encodingString)
throws UnsupportedEncodingException {
// 这里调用淘宝API
String urlStr = “http://ip.taobao.com/service/getIpInfo.php”;
// 从http://whois.pconline.com.cn取得IP所在的省市区信息
String returnStr = getResult(urlStr, content, encodingString);
if (returnStr != null) {
// 处理返回的省市区信息
System.out.println("(1) unicode转换成中文前的returnStr : " + returnStr);
returnStr = decodeUnicode(returnStr);
System.out.println("(2) unicode转换成中文后的returnStr : " + returnStr);
String[] temp = returnStr.split(",");
if (temp.length < 3) {
return “0”;//无效IP,局域网测试
}
return returnStr;
}
return null;
}
/**
- @param urlStr 请求的地址
- @param content 请求的参数 格式为:name=xxx&pwd=xxx
- @param encoding 服务器端请求编码。如GBK,UTF-8等
- @return
/
private static String getResult(String urlStr, String content, String encoding) {
URL url = null;
HttpURLConnection connection = null;
try {
url = new URL(urlStr);
connection = (HttpURLConnection) url.openConnection();// 新建连接实例
connection.setConnectTimeout(8000);// 设置连接超时时间,单位毫秒
connection.setReadTimeout(8000);// 设置读取数据超时时间,单位毫秒
connection.setDoOutput(true);// 是否打开输出流 true|false
connection.setDoInput(true);// 是否打开输入流true|false
connection.setRequestMethod(“POST”);// 提交方法POST|GET
connection.setUseCaches(false);// 是否缓存true|false
connection.connect();// 打开连接端口
DataOutputStream out = new DataOutputStream(connection
.getOutputStream());// 打开输出流往对端服务器写数据
out.writeBytes(content);// 写数据,也就是提交你的表单 name=xxx&pwd=xxx
out.flush();// 刷新
out.close();// 关闭输出流
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream(), encoding));// 往对端写完数据对端服务器返回数据
// ,以BufferedReader流来读取
StringBuffer buffer = new StringBuffer();
String line = “”;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
reader.close();
return buffer.toString();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (connection != null) {
connection.disconnect();// 关闭连接
}
}
return null;
}
/* - unicode 转换成 中文
- @param theString
- @return
*/
public static String decodeUnicode(String theString) {
char aChar;
int len = theString.length();
StringBuffer outBuffer = new StringBuffer(len);
for (int x = 0; x < len; ) {
aChar = theString.charAt(x++);
if (aChar == ‘\’) {
aChar = theString.charAt(x++);
if (aChar == ‘u’) {
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case ‘0’:
case ‘1’:
case ‘2’:
case ‘3’:
case ‘4’:
case ‘5’:
case ‘6’:
case ‘7’:
case ‘8’:
case ‘9’:
value = (value << 4) + aChar - ‘0’;
break;
case ‘a’:
case ‘b’:
case ‘c’:
case ‘d’:
case ‘e’:
case ‘f’:
value = (value << 4) + 10 + aChar - ‘a’;
break;
case ‘A’:
case ‘B’:
case ‘C’:
case ‘D’:
case ‘E’:
case ‘F’:
value = (value << 4) + 10 + aChar - ‘A’;
break;
default:
throw new IllegalArgumentException(
“Malformed encoding.”);
}
}
outBuffer.append((char) value);
}
else {
if (aChar == ‘t’) {
aChar = ‘\t’;
}
else if (aChar == ‘r’) {
aChar = ‘\r’;
}
else if (aChar == ‘n’) {
aChar = ‘\n’;
}
else if (aChar == ‘f’) {
aChar = ‘\f’;
}
outBuffer.append(aChar);
}
}
else {
outBuffer.append(aChar);
}
}
return outBuffer.toString();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
如何调用
// 测试
public static void main(String[] args) throws Exception {
AddressUtils addressUtils = new AddressUtils();
String ip = "222.221.10.111";
String address = "";
try {
address = addressUtils.getAddresses("ip=" + ip, "utf-8");
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
JSONObject jsonObject = new JSONObject(address);
jsonObject = jsonObject.getJSONObject("data");
//通过相应的get方法,获取相应的属性
String county = jsonObject.getString("country_id");//国家
String region = jsonObject.getString("region");//省份
String city = jsonObject.getString("city");//城市
String telecom = jsonObject.getString("isp");//运营商
System.out.println("获取的地址为:" + address);
System.out.println("解析得到的地址为:" +county+","+ region + "省;" + city + "市,"+telecom);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
效果图
在这里插入图片描述
注意事项
案例中使用的解析地址是淘宝的,也提供了一个新浪的,这些都是免费的api。但是,我说但是了啊,这些免费的api使用起来有一个bug;那就是:如果你频繁调用这个接口,会出现502,调用失败的显现。那么,如何解决这个问题呢?好说,充钱。没错,就是充钱购买比如阿里云提供的一个这样的工具,收费的;
当然,除了充钱,也还有第二个解决方案。在说第二种解决方案之前,我们先来了解一下上面的第一种解决方案的思路:
实现思路
将全球申请的ip地址信息收集起来,做成一个数据库系统,存入服务器端。当需要使用查询的时候,直接使用IP地址和数据库系统中的数据进行对比(因为ip地址在全球都是唯一的,在存入数据库之前,会将IP地址转为一个二进制数字然后进行存储,需要查询的时候也同样是将提供IP地址转为一个二进制数字再进行查询)。
第二种解决方案
在大致了解了这个功能的实现过程以后,我们对于第二种解决方案应该也成竹在胸了。没错,那就是我们自己下载ip地址信息,存储在本地,需要使用的时候,直接在本地查询对比即可。
那么,这个IP地址信息去哪里下载呢?以下是下载地址:http://software77.net/geo-ip/
具体的编写流程由于时间等原因,本次就不做介绍了。下回有时间再来唠叨唠叨