通过百度普通IP定位API获取IP的地理位置java根据ip定位地理位置

在项目开发中,需要在登录日志或者操作日志中记录客户端ip所在的地理位置。目前根据ip定位地理位置的第三方api有好几个,淘宝、新浪、百度等,这三种其实也有些缺点的:淘宝,开始几次可以成功根据ip获取对应地理位置,但后面就莫名其妙开始不行,直接通过浏览器获取又可以;新浪,之前一直可以,但最近不知道为什么不行了,访问直接报错(可能api修改了或者取消了吧);百度,需要申请百度地图开发者平台的开发者账号,请求时接口中需要加上百度提供的秘钥等信息,好像不能定位国外的ip,但是针对国内的可以使用。在此整理一下,便于后期使用。

百度Web服务API-普通IP定位:http://lbsyun.baidu.com/index.php?title=webapi/ip-api

根据以上使用指南,注册百度账号,成为地图开放平台开发者,获取密钥(AK),根据服务文档使用。

一、首先获取IP地址

java IP地址工具类,java IP地址获取,java获取客户端IP地址

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

public class IpUtils {

	private static final String[] HEADERS = { 
        "X-Forwarded-For",
        "Proxy-Client-IP",
        "WL-Proxy-Client-IP",
        "HTTP_X_FORWARDED_FOR",
        "HTTP_X_FORWARDED",
        "HTTP_X_CLUSTER_CLIENT_IP",
        "HTTP_CLIENT_IP",
        "HTTP_FORWARDED_FOR",
        "HTTP_FORWARDED",
        "HTTP_VIA",
        "REMOTE_ADDR",
        "X-Real-IP"
	};
	
	/**
	 * 判断ip是否为空,空返回true
	 * @param ip
	 * @return
	 */
	public static boolean isEmptyIp(final String ip){
        return (ip == null || ip.length() == 0 || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip));
    }
	
	
	/**
	 * 判断ip是否不为空,不为空返回true
	 * @param ip
	 * @return
	 */
	public static boolean isNotEmptyIp(final String ip){
        return !isEmptyIp(ip);
    }
	
	/***
     * 获取客户端ip地址(可以穿透代理)
     * @param request HttpServletRequest
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
    	String ip = "";
    	for (String header : HEADERS) {
            ip = request.getHeader(header);
            if(isNotEmptyIp(ip)) {
            	 break;
            }
        }
        if(isEmptyIp(ip)){
        	ip = request.getRemoteAddr();
        }
        if(isNotEmptyIp(ip) && ip.contains(",")){
        	ip = ip.split(",")[0];
        }
        if("0:0:0:0:0:0:0:1".equals(ip)){
            ip = "127.0.0.1";
        }
        return ip;
    }
	
    
    /**
	 * 获取本机的局域网ip地址,兼容Linux
	 * @return String
	 * @throws Exception
	 */
	public String getLocalHostIP() throws Exception{
		Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
		String localHostAddress = "";
		while(allNetInterfaces.hasMoreElements()){
			NetworkInterface networkInterface = allNetInterfaces.nextElement();
			Enumeration<InetAddress> address = networkInterface.getInetAddresses();
			while(address.hasMoreElements()){
				InetAddress inetAddress = address.nextElement();
				if(inetAddress != null && inetAddress instanceof Inet4Address){
					localHostAddress = inetAddress.getHostAddress();
				}
			}
		}
		return localHostAddress;
	}
	
	
}

 转载自:https://www.iteye.com/blog/fanshuyao-2436489

二、百度普通IP定位API获取地理位置

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import org.json.JSONException;
import org.json.JSONObject;

public class Ip2LocationViaBaidu {
	/**
	 * 根据IP查询地理位置
	 * @param ip
	 *            查询的地址
	 * @return status
	 * 				0:正常
	 * 				1:API查询失败
	 * 				2:API返回数据不完整
	 * @throws IOException
	 * @throws JSONException
	 */
	public static Object[] getLocation(String ip) throws IOException, JSONException {
		String lng = null;// 经度
		String lat = null;// 纬度
		String province=null;//省
		String city = null;// 城市名
		
		
		String status = "0";// 成功
		String ipString = null;
		String jsonData = ""; // 请求服务器返回的json字符串数据
		
		try {
			ipString = java.net.URLEncoder.encode(ip, "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		
	    /*
	     * 请求URL
	    	http://api.map.baidu.com/location/ip?ak=您的AK&ip=您的IP&coor=bd09ll //HTTP协议 
	    	https://api.map.baidu.com/location/ip?ak=您的AK&ip=您的IP&coor=bd09ll //HTTPS协议
	    */
		String key = "*************";// 百度密钥(AK),此处换成自己的AK
		String url = String.format("https://api.map.baidu.com/location/ip?ak=%s&ip=%s&coor=bd09ll", key, ipString);// 百度普通IP定位API
		URL myURL = null;
		URLConnection httpsConn = null;
		try {
			myURL = new URL(url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		InputStreamReader insr = null;
		BufferedReader br = null;
		try {
			httpsConn = (URLConnection) myURL.openConnection();// 不使用代理
			if (httpsConn != null) {
				insr = new InputStreamReader(httpsConn.getInputStream(), "UTF-8");
				br = new BufferedReader(insr);
				String data = null;
				int count = 1;
				while ((data = br.readLine()) != null) {
					jsonData += data;
				}
				JSONObject jsonObj = new JSONObject(jsonData);
				if ("0".equals(jsonObj.getString("status"))) {
					province = jsonObj.getJSONObject("content").getJSONObject("address_detail").getString("province");
					city = jsonObj.getJSONObject("content").getJSONObject("address_detail").getString("city");

					lng = jsonObj.getJSONObject("content").getJSONObject("point").getString("x");
					lat = jsonObj.getJSONObject("content").getJSONObject("point").getString("y");
					if (city.isEmpty() || lng.isEmpty() || lat.isEmpty()) {
						status = "2";// API返回数据不完整
					}
				} else {
					status = "1";// API查询失败
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (insr != null) {
				insr.close();
			}
			if (br != null) {
				br.close();
			}
		}
		return new Object[] { status, province, city, lng, lat };
	}
}

把上边的百度密钥换成你自己的,下边是API返回的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    #返回状态码  
}

转载自: https://my.oschina.net/wukongcelebrity/blog/859892

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个Java代码示例,它使用IP地址获取来源地信息。您需要使用IP地址查询API获取该信息。下面是代码示例: 首先,您需要添加以下依赖项到您的pom.xml文件中: ```xml <dependency> <groupId>com.maxmind.geoip2</groupId> <artifactId>geoip2</artifactId> <version>2.14.0</version> </dependency> ``` 然后,您可以创建一个名为GeoService的服务类,如下所示: ```java public class GeoService { private DatabaseReader dbReader; public GeoService() throws IOException { InputStream dbStream = getClass().getResourceAsStream("/GeoLite2-City.mmdb"); dbReader = new DatabaseReader.Builder(dbStream).build(); } public String getCityByIp(String ipAddress) throws IOException, GeoIp2Exception { InetAddress inetAddress = InetAddress.getByName(ipAddress); CityResponse response = dbReader.city(inetAddress); return response.getCity().getName(); } } ``` 在这个示例中,我们使用了MaxMind提供的GeoIP2 Java API,它允许我们根据IP地址查询地理位置信息。我们在服务类中初始化了一个DatabaseReader对象,该对象负责从GeoLite2-City.mmdb文件中读取数据库。然后,我们提供了一个公共方法来获取城市名称,该方法接受一个IP地址参数,并返回城市名称。 最后,您可以在主函数中使用此服务类,如下所示: ```java public static void main(String[] args) { try { GeoService geoService = new GeoService(); String city = geoService.getCityByIp("123.123.123.123"); System.out.println(city); } catch (IOException | GeoIp2Exception e) { e.printStackTrace(); } } ``` 在这个示例中,我们创建了一个GeoService对象,并使用它来查询IP地址“123.123.123.123”的城市名称。您可以根据自己的需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值