概述
本文主要内容:使用第三方平台(百度地图开放平台)通过ip获取对应的城市信息。
使用场景
以城市为分类的应用和网站,根据客户通过HTTP/HTTPS协议访问后端服务时携带的IP来提供对应城市的服务。
后端服务根据请求获取IP
import javax.servlet.http.HttpServletRequest;
public class MyWebUtils {
public static String getRealRemoteHost(HttpServletRequest request) {
String ip = request.getHeader("X-FORWARDED-FOR");
if (ip == null) {
ip = request.getRemoteAddr();
} else {
int idx = ip.indexOf(",");
if (idx > -1) {
ip = ip.substring(0, idx);
}
}
return ip;
}
}
根据IP获取位置信息
访问百度地图给的HTTP/HTTPS接口,就会得到这个IP对应的粗略的位置信息。这些信息是JSON格式的字符串,其格式如下:
{
address: "CN|北京|北京|None|CHINANET|1|None", #地址
content: #详细内容
{
address: "北京市", #简要地址
address_detail: #详细地址信息
{
city: "北京市", #城市
city_code: 131, #百度城市代码
district: "", #区县
province: "北京市", #省份
street: "", #街道
street_number: "" #门址
},
point: #当前城市中心点,注意当前坐标返回类型
{
x: "116.39564504",
y: "39.92998578"
}
},
status: 0 #返回状态码
}
若想要了解更多的信息请查看百度地图开放平台文档说明。
下面看怎样通过Java程序获取某个IP的位置信息。
import com.google.gson.Gson;
import org.apache.commons.lang3.StringEscapeUtils;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
/**
* Created by yrs on 2017/7/21.
*/
public class Location {
//在百度地图开放平台申请的密钥
private static final String BAIDU_AK = "******";
public static String sendGet(String url) {
String result = "";
BufferedReader bf = null;
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 定义 BufferedReader输入流来读取URL的响应
bf = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = bf.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (bf != null) {
bf.close();
}
} catch (IOException e2) {
System.out.println("关闭BufferedReader出现异常!" + e);
e2.printStackTrace();
}
}
return result;
}
public static Map getLocationInfo(String url, String ip) {
String urlAndParam = url + "?ak=" + BAIDU_AK + "&ip=" + ip;
String unicodeJsonStr = sendGet(urlAndParam);
//反转义unicode字符串
String jsonStr = StringEscapeUtils.unescapeJson(unicodeJsonStr);
Gson gson = new Gson();
Map locationInfoMap = gson.fromJson(jsonStr, HashMap.class);
return locationInfoMap;
}
public static void main(String [] args) {
Map map = getLocationInfo("http://api.map.baidu.com/location/ip", "122.114.65.169");
if ((Double)map.get("status") == 0) {
Map content = (Map)map.get("content");
System.out.println("address: " + content.get("address"));
}
}
}
输出:
address: 河南省郑州市
其他
高德开放平台也有提供IP定位,百度平台和高德平台之间的区别主要在使用限制上,高德平台单个key支持一万次/分钟调用,日调用次数不限量。百度平台的调用次数有分类:
另外高德平台只支持HTTP协议类型访问访问,百度平台支持HTTP和HTTPS协议类型访问。返回信息两个平台都差不多,虽然百度平台返回的字段多一点,但是里面的区县、街道、门址往往都是空的。