java实现根据ip地址获取地理位置
最近项目某个功能需要根据ip地址从第三方接口获取详细的地理位置,从网上找了很多例子,主要接口有新浪的,淘宝的,腾讯的。试了淘宝的,如果是数量级小的还可以,如果数量级达到上十万级就速度慢了,会导致系统崩溃。下面例子是新浪的,例子不是适合每个项目,需要改一下.
/** ipSearchUrl=http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=(这是新浪的接口地址) 在项目中新浪的接口地址没有直接写死,而是去读属性文件。 */ publicstaticStringgetIpInfoBySina(Stringip){ //读取属性文件(属性文件key-value和格式) finalStringPROP_IPSEARCHURL="ipSearchUrl"; finalStringRET_SUCCESS="1"; finalStringRET="ret"; finalStringPROVINCE="province"; finalStringCITY="city"; finalStringDISTRICT="district"; finalStringISP="isp"; StringipAddress=""; if(StringUtils.isBlank(ip)){ returnnull; } Stringurl=SystemParamPropertyUtils.getSystemParamKeyValue(PROP_IPSEARCHURL);//这个是从属性文件中获取url,即新浪接口地址 if(StringUtils.isNotBlank(url)){ Stringpath=url+ip;//"http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip="+ip; HttpClienthttpClient=newHttpClient(); Map<String,String>paramMap=newHashMap<String,String>(); StringremoteIpInfo=""; try{ remoteIpInfo=HttpClientUtil.request(httpClient,path,paramMap,"sina"); }catch(Exceptione){ e.printStackTrace(); } if(StringUtils.isNotBlank(remoteIpInfo)){ String_ret=searchValue(remoteIpInfo,RET); if(RET_SUCCESS.equals(_ret)){ StringprovinceName=searchValue(remoteIpInfo,PROVINCE); StringcityName=searchValue(remoteIpInfo,CITY); Stringdistrict=searchValue(remoteIpInfo,DISTRICT); Stringisp=searchValue(remoteIpInfo,ISP); ipAddress=provinceName+cityName+district+isp; } } } returnipAddress; } privatestaticStringsearchValue(StringremoteIpInfo,Stringkey){ 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不一样。我不知道怎么解决。有大神知道回我一下。
下面是用淘宝的。
importjava.io.BufferedReader; importjava.io.DataOutputStream; importjava.io.IOException; importjava.io.InputStreamReader; importjava.io.UnsupportedEncodingException; importjava.net.HttpURLConnection; importjava.net.URL; /** *根据IP地址获取详细的地域信息 *@authorLwl *@dateJan26,2016 */ publicclassAddressUtils{ /** * *@paramcontent *请求的参数格式为:name=xxx&pwd=xxx *@paramencoding *服务器端请求编码。如GBK,UTF-8等 *@return *@throwsUnsupportedEncodingException */ publicStringgetAddresses(Stringcontent,StringencodingString) throwsUnsupportedEncodingException{ //这里调用pconline的接口 StringurlStr="http://ip.taobao.com/service/getIpInfo.php"; //从http://whois.pconline.com.cn取得IP所在的省市区信息 StringreturnStr=this.getResult(urlStr,content,encodingString); if(returnStr!=null){ //处理返回的省市区信息 System.out.println(returnStr); String[]temp=returnStr.split(","); if(temp.length<3){ return"0";//无效IP,局域网测试 } Stringregion=(temp[5].split(":"))[1].replaceAll("\"",""); region=decodeUnicode(region);//省份 Stringcountry=""; Stringarea=""; //Stringregion=""; Stringcity=""; Stringcounty=""; Stringisp=""; for(inti=0;i<temp.length;i++){ switch(i){ case1: country=(temp[i].split(":"))[2].replaceAll("\"",""); country=decodeUnicode(country);//国家 break; case3: area=(temp[i].split(":"))[1].replaceAll("\"",""); area=decodeUnicode(area);//地区 break; case5: region=(temp[i].split(":"))[1].replaceAll("\"",""); region=decodeUnicode(region);//省份 break; case7: city=(temp[i].split(":"))[1].replaceAll("\"",""); city=decodeUnicode(city);//市区 break; case9: county=(temp[i].split(":"))[1].replaceAll("\"",""); county=decodeUnicode(county);//地区 break; case11: isp=(temp[i].split(":"))[1].replaceAll("\"",""); isp=decodeUnicode(isp);//ISP公司 break; } } System.out.println(country+area+region+city+county+isp); returnnewStringBuffer(country).append(area).append(region).append(city).append(county).append(isp).toString(); } returnnull; } /** *@paramurlStr *请求的地址 *@paramcontent *请求的参数格式为:name=xxx&pwd=xxx *@paramencoding *服务器端请求编码。如GBK,UTF-8等 *@return */ privateStringgetResult(StringurlStr,Stringcontent,Stringencoding){ URLurl=null; HttpURLConnectionconnection=null; try{ url=newURL(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();//打开连接端口 DataOutputStreamout=newDataOutputStream(connection.getOutputStream());//打开输出流往对端服务器写数据 out.writeBytes(content);//写数据,也就是提交你的表单name=xxx&pwd=xxx out.flush();//刷新 out.close();//关闭输出流 BufferedReaderreader=newBufferedReader(newInputStreamReader( connection.getInputStream(),encoding));//往对端写完数据对端服务器返回数据 //,以BufferedReader流来读取 StringBufferbuffer=newStringBuffer(); Stringline=""; while((line=reader.readLine())!=null){ buffer.append(line); } reader.close(); returnbuffer.toString(); }catch(IOExceptione){ e.printStackTrace(); }finally{ if(connection!=null){ connection.disconnect();//关闭连接 } } returnnull; } /** *unicode转换成中文 * *@authorfanhui2007-3-15 *@paramtheString *@return */ publicstaticStringdecodeUnicode(StringtheString){ charaChar; intlen=theString.length(); StringBufferoutBuffer=newStringBuffer(len); for(intx=0;x<len;){ aChar=theString.charAt(x++); if(aChar=='\\'){ aChar=theString.charAt(x++); if(aChar=='u'){ intvalue=0; for(inti=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: thrownewIllegalArgumentException( "Malformedencoding."); } } outBuffer.append((char)value); }else{ if(aChar=='t'){ aChar='\t'; }elseif(aChar=='r'){ aChar='\r'; }elseif(aChar=='n'){ aChar='\n'; }elseif(aChar=='f'){ aChar='\f'; } outBuffer.append(aChar); } }else{ outBuffer.append(aChar); } } returnoutBuffer.toString(); } //测试 publicstaticvoidmain(String[]args){ AddressUtilsaddressUtils=newAddressUtils(); //测试ip219.136.134.157中国=华南=广东省=广州市=越秀区=电信 Stringip="125.70.11.136"; Stringaddress=""; try{ address=addressUtils.getAddresses("ip="+ip,"utf-8"); }catch(UnsupportedEncodingExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } System.out.println(address); //输出结果为:广东省,广州市,越秀区 } }