java根據IP地址獲取本地定位

          在很多項目裏,對當前用戶的地理位置定位是一個很重要和“貼心”的需求。

     通過定位服務,我們可以提供用戶對周邊地區服務的認知和響應,對服務型軟件的產品也是一個非常好的體驗點。

     比如有一款手機軟件叫“指路精靈”,設計的就非常實用,大家可以查查看:它通過自動用戶定位,只需選中你需要的服務項,如“娛樂”,再轉動手機,他就能自動獲取周圍一定範圍內的娛樂場所信息,並提供地圖服務等,非常方便。

     可以說就是通過一箇中心節點,擴展成了網,爲用戶提供更有深度的服務。

     這次我們就來給大家介紹一下,如何通過IP地址(無線網用戶定位到外網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;  
import org.jsoup.Connection;  //這個jsoup包需要引一下,大家自行百度吧
import org.jsoup.Jsoup;

/** 
 *  根據IP地址獲取本地定位 
 */
public class AddressUtils {
	 
    /** 
     * 得到本機的外網ip,出現異常時返回空串"" 
     * @return 
     */  
    public static String getPublicIP() {  
        String ip = "";  
          
        org.jsoup.nodes.Document doc = null;  
        Connection con = null;  
  
        con = Jsoup.connect("http://www.ip138.com/ip2city.asp").timeout(10000);   
  
        try {  
            doc = con.get();  
              
            // 獲得包含本機ip的文本串:您的IP是:[xxx.xxx.xxx.xxx] 
            org.jsoup.select.Elements els = doc.body().select("center");  
            for (org.jsoup.nodes.Element el : els) {  
                ip = el.text();   
            }  
              
            // 從文本串過濾出ip,用正則表達式將非數字和.替換成空串""  
            ip = ip.replaceAll("[^0-9.]", "");   
        } catch (IOException e) {  
            e.printStackTrace();  
            return ip;  
        }  
        return ip;  
    }  
	
	 /** 
	  * @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);// 設置連接超時時間,單位毫秒,如果運行時出現超時,可自行增大超時時間,如加到10000
	   connection.setReadTimeout(2000);// 設置讀取數據超時時間,單位毫秒  
	   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 轉換成 中文 
	  * 
	  * @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();  
	 }  
	 
	 /** 
	  * 
	  * @param content 
	  *            請求的參數 格式爲:name=xxx&pwd=xxx 
	  * @param encoding 
	  *            服務器端請求編碼。如GBK,UTF-8等 
	  * @return 
	  * @throws UnsupportedEncodingException 
	  */  
	 public String getAddresses(String content, String encodingString)  
	   throws UnsupportedEncodingException {  
	  // 這裏調用PC-Online的接口  
	  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 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;  
	                }  
	            }   
	   return region;  
	  }  
	  return null;  
	 }  
	 
	 // 這裏我們舉的例子是獲取所在地省份名稱,也可以改變上邊getAddress的返回值,獲取具體的市縣名
	 public static String getProvinceName(){
		 AddressUtils addressUtils = new AddressUtils();  
		  String ip = getPublicIP();  
		  String address = "";  
		  try {  
		   address = addressUtils.getAddresses("ip="+ip, "utf-8");  
		  } catch (UnsupportedEncodingException e) {  
		   e.printStackTrace();  
		  }  
		  return address;
	 }
	 
	 //Main,輸出省名
	 public static void main(String[] args) throws Exception {  
	  String address= getProvinceName();
	  System.out.println(address);  
	 }  
}

      地址定位的基本原理其實就是調用一個外部的開放接口,獲取信息碼後解碼,再轉化成中文輸出。以後再添加天氣提示、本地相關新聞鏈接、本地廣告商服務等接口就都能很輕鬆的融入到我們的系統中服務大衆了~







發佈了145 篇原創文章 · 獲贊 37 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章