java实现根据ip地址获取地理位置

最近项目某个功能需要根据ip地址从第三方接口获取详细的地理位置,从网上找了很多例子,主要接口有新浪的,淘宝的,腾讯的。试了淘宝的,如果是数量级小的还可以,如果数量级达到上十万级就速度慢了,会导致系统崩溃。下面例子是新浪的,例子不是适合每个项目,需要改一下.

/**
 ipSearchUrl=http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=(这是新浪的接口地址)
  在项目中新浪的接口地址没有直接写死,而是去读属性文件。
*/
  public static String getIpInfoBySina(String ip){
   // 读取属性文件(属性文件key-value和格式)
    final String PROP_IPSEARCHURL="ipSearchUrl";
    final String RET_SUCCESS="1";
    final String RET="ret";
    final String PROVINCE="province";
    final String CITY="city";
    final String DISTRICT="district";
    final String ISP="isp";
    String ipAddress="";
    if(StringUtils.isBlank(ip)){
      return null;
    }
    String url = SystemParamPropertyUtils.getSystemParamKeyValue(PROP_IPSEARCHURL);//这个是从属性文件中获取url,即新浪接口地址
    if(StringUtils.isNotBlank(url)){
      String path=url+ip;//"http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip="+ip;
      HttpClient httpClient = new HttpClient();
      Map<String, String> paramMap = new HashMap<String, String>();
      String remoteIpInfo="";

      try {
        remoteIpInfo = HttpClientUtil.request(httpClient, path, paramMap,"sina");
      } catch (Exception e) {
        e.printStackTrace();
      }
      if(StringUtils.isNotBlank(remoteIpInfo)){
        String _ret=searchValue(remoteIpInfo, RET);
        if(RET_SUCCESS.equals(_ret)){
          String provinceName=searchValue(remoteIpInfo, PROVINCE);
          String cityName=searchValue(remoteIpInfo, CITY);
          String district=searchValue(remoteIpInfo, DISTRICT);
          String isp=searchValue(remoteIpInfo, ISP);
          ipAddress=provinceName+cityName+district+isp;
        }
      }
    }
    return ipAddress;
  }
 private static String searchValue(String remoteIpInfo,String key){
    String _value="";
   if(StringUtils.isNotBlank(remoteIpInfo)){
     _value=StringUtils.substringBetween(remoteIpInfo,"\""+key+"\":", ",");
     if(StringUtils.isNotBlank(_value)){
        _value=UnicodeUtils.decodeUnicode(_value);
     }
   }
   return _value;
  }

读新浪的接口地址很快,我本人测试到了九万条左右,十分钟。淘宝的话一个多小时,五万多条。还有一个小技巧,就是把读到的ip存到map中,然后下次读的话就直接从map取出,这样快很多。这个会衍生出很多问题,当日志文件达到百万级,千万级,怎么解决。类似淘宝这样的,一秒多少订单,每个订单ip不一样。我不知道怎么解决。有大神知道回我一下。
下面是用淘宝的。


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地址获取详细的地域信息
* @author Lwl
* @dateJan 26, 2016
 */
public class AddressUtils {

/**
 *
 * @param content
 *      请求的参数 格式为:name=xxx&pwd=xxx
 * @param encoding
 *      服务器端请求编码。如GBK,UTF-8等
 * @return
 * @throws UnsupportedEncodingException
 */
 public String getAddresses(String content, String encodingString)
  throws UnsupportedEncodingException {
 // 这里调用pconline的接口
 String urlStr = "http://ip.taobao.com/service/getIpInfo.php";
 // 从http://whois.pconline.com.cn取得IP所在的省市区信息
 String returnStr = this.getResult(urlStr, content, encodingString);
 if (returnStr != null) {
  // 处理返回的省市区信息
  System.out.println(returnStr);
  String[] temp = returnStr.split(",");
  if(temp.length<3){
  return "0";//无效IP,局域网测试
  }
  String region = (temp[5].split(":"))[1].replaceAll("\"", "");
  region = decodeUnicode(region);// 省份 

      String country = "";
      String area = "";
      // String region = "";
      String city = "";
      String county = "";
      String isp = "";
      for (int i = 0; i < temp.length; i++) {
        switch (i) {
        case 1:
          country = (temp[i].split(":"))[2].replaceAll("\"", "");
          country = decodeUnicode(country);// 国家
          break;
          case 3:
            area = (temp[i].split(":"))[1].replaceAll("\"", "");
            area = decodeUnicode(area);// 地区
          break;
          case 5:
            region = (temp[i].split(":"))[1].replaceAll("\"", "");
            region = decodeUnicode(region);// 省份
          break;
          case 7:
            city = (temp[i].split(":"))[1].replaceAll("\"", "");
            city = decodeUnicode(city);// 市区
          break;
          case 9:
              county = (temp[i].split(":"))[1].replaceAll("\"", "");
              county = decodeUnicode(county);// 地区
          break;
          case 11:
            isp = (temp[i].split(":"))[1].replaceAll("\"", "");
            isp = decodeUnicode(isp); // ISP公司
          break;
        }
      } 

  System.out.println(country+area+region+city+county+isp);
  return new StringBuffer(country).append(area).append(region).append(city).append(county).append(isp).toString();
 }
 return null;
 }
 /**
 * @param urlStr
 *      请求的地址
 * @param content
 *      请求的参数 格式为:name=xxx&pwd=xxx
 * @param encoding
 *      服务器端请求编码。如GBK,UTF-8等
 * @return
 */
 private 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(2000);// 设置连接超时时间,单位毫秒
  connection.setReadTimeout(33000);// 设置读取数据超时时间,单位毫秒
  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 转换成 中文
 *
 * @author fanhui 2007-3-15
 * @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();
 }
 // 测试
 public static void main(String[] args) {
 AddressUtils addressUtils = new AddressUtils();
 // 测试ip 219.136.134.157 中国=华南=广东省=广州市=越秀区=电信
 String ip = "125.70.11.136";
 String address = "";
 try {
  address = addressUtils.getAddresses("ip="+ip, "utf-8");
 } catch (UnsupportedEncodingException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 System.out.println(address);
 // 输出结果为:广东省,广州市,越秀区
 } 

}
(0)

相关推荐

  • Java怎么获取多网卡本地ip

    废话不多说了,直接给大家贴代码了,具体代码如下所示: public String getLocalHostName() { String hostName; try { InetAddress addr = InetAddress.getLocalHost(); hostName = addr.getHostName(); } catch (Exception ex) { hostName = ""; } return hostName; } public String[] getAl

  • Java 获取本机的IP与MAC地址实现详解

     Java 获取本机的IP与MAC地址 有些机器有许多虚拟的网卡,获取IP地址时会出现一些意外,所以需要一些验证: // 获取mac地址 public static String getMacAddress() { try { Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces(); byte[] mac = null; while (allNetInterfaces.ha

  • java编程实现获取服务器IP地址及MAC地址的方法

    本文实例讲述了java编程实现获取服务器IP地址及MAC地址的方法.分享给大家供大家参考,具体如下: 已测系统: windows linux unix 排除127.0.0.1 和 0.0.0.0.1等非正常IP import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.ArrayList; import java.util.Enu

  • java中通过网卡名称获取IP地址

    复制代码 代码如下: package me.xuzs.sso.test; import java.net.InetAddress;import java.net.NetworkInterface;import java.net.SocketException;import java.util.Enumeration; public class InternetTest { public static void main(String[] args) {        String netCard

  • 利用Java如何获取IP与机器名方法示例

    前言 本文详细给大家介绍了关于利用Java如何获取IP与机器名的方法示例,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍: 一.通过IP获取机器名 or 通过机器名获取ip host :主机        hostAddress :ip       hostName:机器名 import java.net.InetAddress; import java.net.UnknownHostException; public class Test01 { public static voi

  • java获取ip地址示例

    如果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为http://www.xxx.com/ 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP. 经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端.但是在转发请求的HTTP头信息中,增加了X-FORWARDE

  • Java实现获取客户端真实IP方法小结

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了.如果使用了反向代理软件,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1或192.168.1.110,而并不是客户端的真实IP. 经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的 IP,服务器端应用也无法直接通过转发请

  • java获取注册ip实例

    话不多说,请看实例代码 String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "un

  • java中获取当前服务器的Ip地址的方法

    1.tomcat是一款免费的开源Web服务器,如果部署在本地,那么对应的那么为localhost,对应地址为127.0.0.1. 例子:可以通过http://localhost:8080/项目root值访问,也可以通过http://127.0.0.1/项目root值访问. 如果部署在服务器(linux)系统类,则需要通过服务器的Ip地址进行访问. 2.下面说说怎么获取Ip地址: 获取本地的Ip地址: public static void main(String[] args) { try { I

  • java实现根据ip地址获取地理位置

    最近项目某个功能需要根据ip地址从第三方接口获取详细的地理位置,从网上找了很多例子,主要接口有新浪的,淘宝的,腾讯的.试了淘宝的,如果是数量级小的还可以,如果数量级达到上十万级就速度慢了,会导致系统崩溃.下面例子是新浪的,例子不是适合每个项目,需要改一下. /** ipSearchUrl=http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=(这是新浪的接口地址) 在项目中新浪的接口地址没有直接写死,而是去读属性文件. *

  • java实现根据ip地址获取地理位置的代码分享

    前几天想给网站后台加个解析ip所在地理位置的功能,在网上看了一些博客,找了几段程序,但总觉得写的不够简洁,感觉很啰嗦.下面这个程序,感觉还算简洁,于是整理调试了一下,可以用,程序调用了"腾讯ip分享计划"提供的接口,当然也可以改成ip138提供的接口,不过这两个网站返回的字符串格式有些不同,要分别做解析. public String getAddressByIP() { try { String strIP = "0.0.0.0"; URL url = new UR

  • Python2.7基于淘宝接口获取IP地址所在地理位置的方法【测试可用】

    本文实例讲述了Python2.7基于淘宝接口获取IP地址所在地理位置的方法.分享给大家供大家参考,具体如下: #!/usr/bin/python import sys, os, urllib2, json def get_ip_area(ip): try: apiurl = "http://ip.taobao.com/service/getIpInfo.php?ip=%s" %ip content = urllib2.urlopen(apiurl).read() data = json

  • java根据ip地址获取详细地域信息的方法

    互联网有很多接口可以实现通过ip查询到具体的位置,如下: 通过淘宝IP地址库获取IP位置 请求接口(GET):http://ip.taobao.com/service/getIpInfo.php?ip=[ip地址字串] 响应信息:(json格式的)国家 .省(自治区或直辖市).市(县).运营商 返回数据格式: {"code":0,"data":{"ip":"210.75.225.254","country"

  • Java根据ip地址获取归属地实例详解

    目录 引言 Java 中是如何获取 IP 属地的 首先需要写一个 IP 获取的工具类 内置的三种查询算法 使用方法 项目用到的全部依赖 引言 最近,各大平台都新增了评论区显示发言者ip归属地的功能,例如哔哩哔哩,微博,知乎等等. Java 中是如何获取 IP 属地的 主要分为以下几步 通过 HttpServletRequest 对象,获取用户的 IP 地址 通过 IP 地址,获取对应的省份.城市 首先需要写一个 IP 获取的工具类 因为每一次用户的 Request 请求,都会携带上请求的 IP 

  • php实现根据IP地址获取其所在省市的方法

    根据现有IP地址获取其地理位置(省份,城市等)的方法 function GetIpLookup($ip = ''){ if(empty($ip)){ return '请输入IP地址'; } $res = @file_get_contents('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=' . $ip); if(empty($res)){ return false; } $jsonMatches = array(

  • PHP根据IP地址获取所在城市具体实现

    文件目录: ipLocation-----qqwry----------QQWry.Dat-----ipCity.class.php ipCity.class.php文件代码: 复制代码 代码如下: <?php class ipCity { /**     * 根据ip地址获取对应所在城市     * @param type $userip 用户IP地址     * @return string     */    public function getCity( $userip, $dat_p

  • JAVA获得域名IP地址的方法

    本文实例讲述了JAVA获得域名IP地址的方法.分享给大家供大家参考.具体如下: import java.net.InetAddress; import java.net.UnknownHostException; public class TestInetAddress { InetAddress myIpAddress = null; InetAddress[] myServer = null; public static void main(String args[]) { TestInet

  • java正则表达式判断 ip 地址是否正确解析

    这篇文章主要介绍了java正则表达式判断 ip 地址是否正确解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下 public class ClassWork05 { public static void main(String[] args) { System.out.println(IsIp.isIp("10.10.1.1")); } } class IsIp{ public static boolean isIp(Str

  • Java中的IP地址和InetAddress类使用详解

    Java语言的优势之一是Java程序能访问网络资源.Java提供一系列的类支持Java程序访问网络资源. TCP/IP协议和IP地址 为了进行网络通信,通信双方必须遵守通信协议.目前最广泛使用的是TCP/IP协议,它是Internet中各方所遵循的公共协议.TCP(Transport Control Protocol)是一种传输控制协议,IP(Internet Protocol)是一种网际协议,TCP/IP代表这两个协议的. TCP/IP分为四个层次: 网络接口层:负责接收和发送物理帧: 网络层

随机推荐