最近项目某个功能需要根据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);  
  // 输出结果为:广东省,广州市,越秀区  
 }  
 
 
}
 

根据ip地址从第三方接口获取详细的地理位置的更多相关文章

  1. 分享几个免费IP地址查询API接口

    几个免费IP地址查询API接口 1.IP地址查询接口:http://apis.juhe.cn/ip/ip2addr要先去https://www.juhe.cn/docs/api/...申请APPKEY ...

  2. #实现详细记录登陆过系统的用户,IP地址,shell命令及详细操作的时间

    //实现详细记录登陆过系统的用户,IP地址,shell命令及详细操作的时间 将下面代码加入/etc/profile //history USER_IP = who -u am i 2> /dev ...

  3. C# 设置IP地址及设置自动获取IP

    原文:C# 设置IP地址及设置自动获取IP </pre><pre name="code" class="csharp">1.添加引用&q ...

  4. linux c++ curl 根据IP地址获得当前网络的所在的地理位置

    注意: 可能每个电脑的默认中文编码格式不同,有时会出现乱码,需要对返回内容进行编码转换,或者换成可指定编码格式的接口.如  搜狐IP地址查询接口(可设置编码):http://pv.sohu.com/c ...

  5. 淘宝IP地址库API接口(PHP)通过ip获取地址信息

    淘宝IP地址库网址:http://ip.taobao.com/ 提供的服务包括: 1. 根据用户提供的IP地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家.省.市和运营商. 2. 用 ...

  6. php 获取客户端的真实ip地址 通过第三方网站

    <?php include 'simple_html_dom.php'; // 1获取真实IP地址方式 function get_onlineip() { $ch = curl_init('ht ...

  7. 几个免费IP地址查询API接口

    转:http://blog.csdn.net/ishxiao/article/details/52670242 -------------------------------------------- ...

  8. 七、环回接口ip地址(逻辑接口)

    loopback接口,在网络设备(一般是路由器)上是一种特殊的接口,它不是物理接口,而是一种看不见摸不着的逻辑接口(也称虚拟接口),但是对于网络设备来说却是至关重要的. 在网络设备上可以通过配置命令来 ...

  9. 输入网址调用第三方接口获取结果_java

    最近公司给了一个第三方服务的网址,要我调用后返回需要用到的信息 具体网址:http://www.xxxx.com/xxx-api/xxxx/getXxxByUserId?userId=" + ...

随机推荐

  1. u-boot 环境变量参数设置

    今天本来是烧写内核,结果一不小心把uboot也整不能用了,无奈之下只好重新烧个uboot,等都弄好以后,发现系统还是启动不了,原来是启动参数设置不对,于是找到了这篇文章,//是我添加的内容. 原文地址 ...

  2. CXF之二(CXF发布webService)

    Apache CXF提供了用于方便地构建和开发WebService的可靠基础架构.它允许创建高性能和可扩展的服务,可以部署在Tomcat和基于spring的轻量级容器中,也可以部署在更高级的服务器上, ...

  3. android 实现模拟按键

    android 实现模拟按键方法一 通过Runtime实现,代码如下: try { String keyCommand = "input keyevent " + KeyEvent ...

  4. NOIP2005 过河

    过河 (river.pas/c/cpp) [问题描述] 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正 ...

  5. htmlcss笔记--a

    a标签 1.下载:href里面放一个文件或者压缩包时,会下载: 2.锚点:跳转到锚点: href="#id" 跳转到的模块添加一个id,点击id就会跳转到该模块. html标签: ...

  6. North America Qualifier (2015)

    https://icpc.baylor.edu/regionals/finder/north-america-qualifier-2015 一个人打.... B 概率问题公式见代码 #include ...

  7. HW7.3

    public class Solution { public static void main(String[] args) { char[][] answers = { {'A', 'B', 'A' ...

  8. leetcode@ [87] Scramble String (Dynamic Programming)

    Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...

  9. MySQL命令使用手记

    1.登陆          >mysql -u root -p,root没密码按回车. 2.创建数据库  >create database XXX; 3.创建用户     >inse ...

  10. nginx变量

    nginx的全局变量参数解释: $arg_PARAMETER#这个变量包含GET请求中,如果有变量PARAMETER时的值. $args   #这个变量等于请求行中(GET请求)的参数,例如foo=1 ...