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);  
	 }  
}

      地址定位的基本原理其实就是调用一个外部的开放接口,获取信息码后解码,再转化成中文输出。以后再添加天气提示、本地相关新闻链接、本地广告商服务等接口就都能很轻松的融入到我们的系统中服务大众了~







评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值