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

作者:GeGe&YoYo 时间:2021-09-11 08:01:07 

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查询失败
* 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    #返回状态码  
}

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

1、添加依赖

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

2、工具类代码

package com.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,省份:浙江省,城市:湖州市                  

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

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

来源:https://blog.csdn.net/weixin_47410172/article/details/127549664

标签:java,IP,地理位置
0
投稿

猜你喜欢

  • mybatis-plus分页查询的实现示例

    2023-11-25 04:57:57
  • Springboot轻量级的监控组件SpringbootAdmin

    2023-08-25 10:08:31
  • C# DataGridView添加新行的2个方法

    2023-06-23 05:42:19
  • Java结构型设计模式中建造者模式示例详解

    2023-04-24 13:37:31
  • java并发编程专题(六)----浅析(JUC)Semaphore

    2023-07-27 23:30:28
  • SpringBoot中JPA实现Sort排序的三种方式小结

    2022-02-12 23:35:12
  • Java Vector和ArrayList的异同分析及实例讲解

    2023-12-03 17:27:10
  • 简单记事本java源码实例

    2023-11-26 02:03:17
  • springboot自动扫描添加的BeanDefinition源码实例详解

    2023-11-24 15:15:22
  • Springboot如何根据实体类生成数据库表

    2023-11-20 13:54:39
  • Java实现添加,读取和删除Excel图片的方法详解

    2023-11-27 06:29:33
  • java修改JFrame默认字体方式

    2022-11-16 14:02:50
  • js 交互在Flutter 中使用 webview_flutter

    2023-07-20 22:40:14
  • Java中计算时间差的方法

    2023-11-15 10:35:44
  • jsp如何获取Session中的值

    2023-07-01 05:59:28
  • Spring Boot统一异常处理最佳实践(拓展篇)

    2023-10-29 16:00:04
  • 如何在IDE部署springboot项目(有swagger和无swagger都是一样的)到服务器或者虚拟机上的docker

    2023-09-01 00:33:25
  • Springboot使用POI实现导出Excel文件示例

    2021-09-22 08:18:31
  • c# socket编程udp客户端实现代码分享

    2023-06-16 05:03:31
  • Android异常 java.lang.IllegalStateException解决方法

    2023-07-28 10:26:36
  • asp之家 软件编程 m.aspxhome.com