开发者

java如何通过IP解析地理位置

目录
  • Java通过IP解析地理位置
    • 获取IP地址
    • 百度普通IP定位API获取地理位置
  • java获取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;
      	}
      }
      

      百度普通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查询失败
      	开发者_Python培训 * 				2:AphpPI返回数据不完整
      	 * @thrUbrKFHrows 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();
      			UbrKFHr}
      			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    #返回状态码  
      }
      

      java获取IP归属地(省、市)

      1、添加依赖

      <dependency>
      	<groupId>com.alibaba</groupId>
      	<artifactId>fastjson</artifactId>
      	<version>1.2.3</version>
      </dependency>

      2、工具类代码

      package cowww.devze.comm.shucha.deveiface.biz.test;
       
       
      /**
       * @author tqf
       * @Description 根据ip获取归属地
       * @Version 1.0
       * @since 2022-05-27 10:11
       */
       
      import cn.hutool.core.util.StrUtil;
      import cn.hutool.http.HttpUtil;
      import com.alibaba.fastjson.JSON;
      import com.alibaba.fastjson.JSONObject;
      import com.itextpdf.text.log.Logger;
      import com.itextpdf.text.log.LoggerFactory;
      import lombok.Data;
      import org.apache.commons.lang3.StringUtils;
      import javax.servlet.http.HttpServletRequest;
      public class iptes {
          private static Logger logger = LoggerFactory.getLogger(iptes.class);
       
          /**
           * 获取IP地址
           *
           * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
           * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
           */
          public static String getIpAddr(HttpServletRequest request) {
              String ip = null;
              try {
                  ip = request.getHeader("x-forwarded-for");
                  if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                      ip = request.getHeader("Proxy-Client-IP");
                  }
                  if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                      ip = request.getHeader("WL-Proxy-Client-IP");
                  }
                  if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                      ip = request.getHeader("HTTP_CLIENT_IP");
                  }
                  if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                      ip = request.getHeader("HTTP_X_FORWARDED_FOR");
                  }
                  if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                      ip = request.getRemoteAddr();
                  }
              } catch (Exception e) {
                  logger.error("IPUtils ERROR ", e);
              }
       
              //使用代理,则获取第一个IP地址
              if(StringUtils.isEmpty(ip) ) {
                  if(ip.indexOf(",") > 0) {
                      ip = ip.substring(0, ip.indexOf(","));
                  }
              }
       
              return ip;
          }
       
          /**
           * 根据ip获取归属地
           * @param ip
           * @return
           */
          public static IpAddress getAddress(String ip) {
              String url = "http://ip.ws.126.net/ipquery?ip=" + ip;
              String str = HttpUtil.get(url);
              if(!StrUtil.hasBlank(str)){
                  String substring = str.substring(str.indexOf("{"), str.indexOf("}")+1);
                  JSONObject jsonObject = JSON.parseobject(substring);
                  String province = jsonObject.getString("province");
                  String city = jsonObject.getString("city");
                  IpAddress ipAddress = new IpAddress();
                  ipAddress.setProvince(province);
                  ipAddress.setCity(city);
                  System.out.println("ip:"+ ip + ",省份:" + province + ",城市:" + city);
                  return ipAddress;
              }
              return null;
          }
       
          @Data
          public static class IpAddress{
              private String province;
              private String city;
          }
       
          public static void main(String[] args) {
              System.out.println(getAddress("36.25.225.250"));
          }
       
      }

      3、测试结果

      测试ip:36.25.225.250

      返回数据:

      ip:36.25.225.250,省份:浙江省,城市:湖州市http://www.devze.com                  

      iptes.IpAddress(province=浙江省, city=湖州市)

      java如何通过IP解析地理位置

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜