SoFunction
Updated on 2025-03-08

Java implementation to obtain geographical location based on IP address

Recently, a certain function of the project needs to obtain detailed geographical location from a third-party interface based on the IP address. I have found many examples from the Internet, including Sina, Taobao, and Tencent. I tried Taobao. If it is a small order of magnitude, it is OK. If it reaches a level of 100,000, the speed will be slow, which will cause the system to crash. The following example is from Sina. The example is not suitable for each project and needs to be modified.

/**
  ipSearchUrl=/iplookup/?format=js&ip= (this is Sina's interface address)
   In the project, Sina's interface address was not written directly, but read the attribute file.
 */
  public static String getIpInfoBySina(String ip){
   // Read attribute file (property file key-value and format)    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((ip)){
      return null;
    }
    String url = (PROP_IPSEARCHURL);//This is to get the url from the attribute file, that is, the Sina interface address    if((url)){
      String path=url+ip;//"/iplookup/?format=js&ip="+ip;
      HttpClient httpClient = new HttpClient();
      Map<String, String> paramMap = new HashMap<String, String>();
      String remoteIpInfo="";
      
      try {
        remoteIpInfo = (httpClient, path, paramMap,"sina");
      } catch (Exception e) {
        ();
      }
      if((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((remoteIpInfo)){
     _value=(remoteIpInfo,"\""+key+"\":", ",");
     if((_value)){
        _value=(_value);        
     }
   }  
   return _value;
  }

I read the Sina interface address very quickly. I tested it for about 90,000, ten minutes. For Taobao, more than an hour, more than 50,000 pieces. There is another trick, which is to save the read ip into the map, and then take it out directly from the map if you read it next time, which is much faster. This will lead to many problems. When the log files reach the millions or tens of millions, how to solve them? For examples like Taobao, each order is different in number of orders in one second. I don't know how to solve it. Some great god knows to reply to me.
The following is Taobao.

 
import ;
import ;
import ;
import ;
import ;
import ;
import ;

/**
  * Get detailed geographical information based on IP address
 * @author Lwl
 * @dateJan 26, 2016
  */
public class AddressUtils {
 
/**
  *
  * @param content
  * The requested parameters format is: name=xxx&pwd=xxx
  * @param encoding
  * Server-side request encoding.  Such as GBK, UTF-8, etc.
  * @return
  * @throws UnsupportedEncodingException
  */ 
 public String getAddresses(String content, String encodingString) 
  throws UnsupportedEncodingException { 
 // Here we call the pconline interface String urlStr = "/service/"; 
 // Get the information of the province, city and district where the IP is located String returnStr = (urlStr, content, encodingString); 
 if (returnStr != null) { 
  // Process the returned provincial, municipal and district information  (returnStr); 
  String[] temp = (","); 
  if(<3){ 
  return "0";//Invalid IP, LAN test  } 
  String region = (temp[5].split(":"))[1].replaceAll("\"", ""); 
  region = decodeUnicode(region);// Province  
      String country = ""; 
      String area = ""; 
      // String region = ""; 
      String city = ""; 
      String county = ""; 
      String isp = ""; 
      for (int i = 0; i < ; i++) { 
        switch (i) { 
        case 1: 
          country = (temp[i].split(":"))[2].replaceAll("\"", ""); 
          country = decodeUnicode(country);// nation          break; 
          case 3: 
            area = (temp[i].split(":"))[1].replaceAll("\"", ""); 
            area = decodeUnicode(area);// area          break; 
          case 5: 
            region = (temp[i].split(":"))[1].replaceAll("\"", ""); 
            region = decodeUnicode(region);// Province          break;  
          case 7: 
            city = (temp[i].split(":"))[1].replaceAll("\"", ""); 
            city = decodeUnicode(city);// Urban area          break;  
          case 9: 
              county = (temp[i].split(":"))[1].replaceAll("\"", ""); 
              county = decodeUnicode(county);// area          break; 
          case 11: 
            isp = (temp[i].split(":"))[1].replaceAll("\"", ""); 
            isp = decodeUnicode(isp); // ISP company          break; 
        } 
      } 
   
  (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
  * Requested address
  * @param content
  * The requested parameters format is: name=xxx&pwd=xxx
  * @param encoding
  * Server-side request encoding.  Such as GBK, UTF-8, etc.
  * @return
  */ 
 private String getResult(String urlStr, String content, String encoding) { 
 URL url = null; 
 HttpURLConnection connection = null; 
 try { 
  url = new URL(urlStr); 
  connection = (HttpURLConnection) ();// Create a new connection instance  (2000);// Set the connection timeout time, in milliseconds  (33000);// Set the timeout time to read data, in milliseconds  (true);// Whether to open the output stream true|false  (true);// Whether to open the input stream true|false  ("POST");// Submission method POST|GET  (false);// Whether to cache true|false  ();// Open the connection port  DataOutputStream out = new DataOutputStream(());// Open the output stream and write data to the peer server  (content);// Write data, that is, submit your form name=xxx&pwd=xxx  ();// refresh  ();// Turn off the output stream  BufferedReader reader = new BufferedReader(new InputStreamReader( 
   (), encoding));// After writing data to the peer terminal, return data to the peer terminal server  // , read with BufferedReader stream  StringBuffer buffer = new StringBuffer(); 
  String line = ""; 
  while ((line = ()) != null) { 
  (line); 
  } 
  (); 
  return (); 
 } catch (IOException e) { 
  (); 
 } finally { 
  if (connection != null) { 
  ();// Close the connection  } 
 } 
 return null; 
 } 
 /**
  * unicode to Chinese
  *
  * @author fanhui 2007-3-15
  * @param theString
  * @return
  */ 
 public static String decodeUnicode(String theString) { 
 char aChar; 
 int len = (); 
 StringBuffer outBuffer = new StringBuffer(len); 
 for (int x = 0; x < len;) { 
  aChar = (x++); 
  if (aChar == '\\') { 
  aChar = (x++); 
  if (aChar == 'u') { 
   int value = 0; 
   for (int i = 0; i < 4; i++) { 
   aChar = (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."); 
   } 
   } 
   ((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'; 
   } 
   (aChar); 
  } 
  } else { 
  (aChar); 
  } 
 } 
 return (); 
 } 
 // test public static void main(String[] args) { 
 AddressUtils addressUtils = new AddressUtils(); 
 // Test ip 219.136.134.157 China = South China = Guangdong Province = Guangzhou City = Yuexiu District = Telecom String ip = "125.70.11.136"; 
 String address = ""; 
 try { 
  address = ("ip="+ip, "utf-8"); 
 } catch (UnsupportedEncodingException e) { 
  // TODO Auto-generated catch block 
  (); 
 } 
 (address); 
 // The output results are: Guangdong Province, Guangzhou City, Yuexiu District } 
 
 
}