使用Java HttpClient访问淘宝Ip查询接口获取具体位置信息

以前项目中有需要用到过记录客户登入的IP地址,但是并木有具体去查询IP所在的位置,
于是带着好奇心去网上搜索获取IP的详细信息的接口。主要有两个IP查询接口:
    1.新浪接口:http://counter.sina.com.cn/ip?ip=(参数)        //返回一个需要下载的js文件
    2.淘宝接口:http://ip.taobao.com/service/getIpInfo.php?ip= (参数)

淘宝接口说明:

本博文中选择淘宝淘宝接口为例,(虽然此接口并不是https协议,本人为了练习下访问https协议接口的代码,
  添加了SSL连接工厂类,将SSLContext自定义设置为可信任任何证书密钥,并关闭主机名验证)

(核心代码添加了详细注释,以便理解。程序若有不当之处,欢迎批评指正):

下面直接看代码:

请求工具类:
package com.httpclient;

import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.message.BasicNameValuePair;

import org.apache.http.client.entity.UrlEncodedFormEntity;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.NameValuePair;

import com.alibaba.fastjson.JSONObject;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;

/** 
 * TrustStrategy类为生成证书的可依赖性策略,不需要配置SSLContext中的证书管理器
 */
class AnyTrustStrategy implements TrustStrategy{
	@Override
	public boolean isTrusted(X509Certificate[] chain, String authType) 
			throws CertificateException {
		return true;
	}
}

public class HttpClient {
	/*
	 * SSLContext官方解释:
	 * 该类的实例表示一个安全的套接字协议实现,作为安全套接字工厂或SSLEngines的工厂。 
	 * 该类使用一组可选的密钥和信任管理器以及安全随机字节源进行初始化。
	 * Java平台的每个实现都需要支持以下标准的SSLContext协议:TLSv1
	 */
	private SSLContext sslContext;
	
	/*
	 * SSLSocketFactory可用于根据受信任证书列表验证HTTPS服务器的身份,并使用私钥对HTTPS服务器进行身份验证。
	 * 当提供包含一个或多个可信证书的信任存储文件时,SSLSocketFactory将启用服务器身份验证。 
	 * 如果目标HTTPS服务器尝试使用不可信证书进行身份验证,客户端安全套接字将在SSL会话握手期间拒绝连接。
	 */
	private SSLConnectionSocketFactory sslSF;
	
	//密钥证书的存储类
	private KeyStore keyStore;
	
	/*
	 * NameValuePair(简单名称值对节点类型),这个代码多处用于Java像url发送Post请求。
	 * 在发送post请求时用该list来存放 参数喝参数值。
	 */
	private List<NameValuePair> paramsConverter(LinkedHashMap<String, Object> params) {
		List<NameValuePair> nvps = new LinkedList<NameValuePair>();
		//需要排序
        Iterator<String> iterator = params.keySet().iterator();  
        while (iterator.hasNext()) {  
            Object key = iterator.next();  
			nvps.add(new BasicNameValuePair((String)key, (String)params.get(key)));
        }  		
		return nvps;
	}
	
	public HttpClient() {
		//初始化SSL链接工厂
		this.createSSLConnSocketFactory();
	}
	
	private void createSSLConnSocketFactory() {
    	try {
    		/*
    		 * getDefaultType() 返回java安全属性文件中默认类型
    		 */
    		//返回KeyStore指定类型的对象
    		keyStore = KeyStore.getInstance(KeyStore.getDefaultType());	
    		/*
    		 * SSLContexts.custom().load...含义为创建自己定制的SSLContext对象。(信任任何密钥的SSLContext)
    		 */
        	sslContext = SSLContexts.custom().loadTrustMaterial(keyStore, new AnyTrustStrategy()).build();
            /*
             * NoopHostnameVerifier类为关闭主机名验证
             */
        	/*
        	 * SSLConnectionSocketFactory构造方法:(参数分别为:ssl上下文,支持的协议,支持的加密套件,主机名验证)
        	 *  SSLConnectionSocketFactory(SSLContext sslContext, 
        	 *  	String[] supportedProtocols, 
        	 *  	String[] supportedCipherSuites, 
        	 *  	HostnameVerifier hostnameVerifier) 
        	 */
        	sslSF = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1" },
                    null, new NoopHostnameVerifier());
    	} catch (KeyStoreException e) {
    		e.printStackTrace();  	
    	} catch (KeyManagementException e) {
    		e.printStackTrace(); 	
    	} catch (NoSuchAlgorithmException e) {
    		e.printStackTrace(); 	
    	} catch (Exception e) {
    		e.printStackTrace(); 	    		
    	}
    }
    
    public String doGet(String url, LinkedHashMap<String, Object> queryParams) throws IOException {    
        String httpStr = null;
        //创建自己定制的HttpClient实例
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslSF)
                .build();
        try {
        	//URIBuilder类 提供用于统一资源标识符 (Uri)自定义的构造函数
        	URIBuilder uriBuilder = new URIBuilder(url);
        	//设置字符集
    		uriBuilder.setCharset(Charset.forName("UTF-8"));
        	if (queryParams != null && !queryParams.isEmpty()) {
        		//设置参数
        		uriBuilder.setParameters(this.paramsConverter(queryParams));        		
        	}
        	
        	//创建get请求方式对象
            HttpGet httpGet = new HttpGet();
            httpGet.setURI(uriBuilder.build());
            //使用httpclient.excute方法发送请求,并获取返回对象CloseableHttpResponse对象
            CloseableHttpResponse response = httpClient.execute(httpGet);
            try {
            	if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                    	//实体内容以字符串类型输出
                    	httpStr = EntityUtils.toString(entity, "UTF-8");
                    	//使用阿里的开源组件fastjson把unicode转中文
                    	JSONObject obj = JSONObject.parseObject(httpStr);
                        System.out.println(obj.toJSONString());
                    }
                    //确保实体内容被完全关闭
                    EntityUtils.consume(entity);            		
            	}
            } catch (IOException e) {
            	e.printStackTrace();            	
            } finally {
                response.close();
            }
        } catch (IOException e) {
        	e.printStackTrace(); 	        	
        } catch (Exception e) {
        	e.printStackTrace(); 	
        }
        finally {
        	httpClient.close();
        }   	
    	return httpStr;
    }
    
    public String doPost(String url, LinkedHashMap<String, Object> formParams) throws IOException {    
        String httpStr = null;
        /*
         * 把输入参数编码转义为合适内容的类。
         */
        UrlEncodedFormEntity formEntity = null;
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslSF)
                .build();
        try {
        	URIBuilder uriBuilder = new URIBuilder(url);
        	uriBuilder.setCharset(Charset.forName("UTF-8"));

        	HttpPost httpPost = new HttpPost();
            httpPost.setURI(uriBuilder.build());
            
            if (formParams != null && !formParams.isEmpty()) {
                formEntity = new UrlEncodedFormEntity(this.paramsConverter(formParams), "UTF-8");
            	httpPost.setEntity(formEntity);
            }

            CloseableHttpResponse response = httpClient.execute(httpPost);
            try {
            	if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                    	httpStr = EntityUtils.toString(entity, "utf-8");
                    }
                    EntityUtils.consume(entity);            		
            	}
            } finally {
                response.close();
            }
        } catch (IOException e) {
        	e.printStackTrace(); 	        	
        } catch (Exception e) {
        	e.printStackTrace(); 	
        }
        finally {
        	httpClient.close();
        }   	
    	return httpStr;
    }
	    
}




测试类:
package com.test;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;

import org.junit.Test;

import com.httpclient.HttpClient;

public class HttpTest {
	
	@Test
	public void test() {
		String IPStr = "***.***.***.***";
		LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
		try {
			String ip = URLEncoder. encode(IPStr,"utf-8");
			String url = "http://ip.taobao.com/service/getIpInfo.php?ip="+ip;
			HttpClient httpClient = new HttpClient();
			//Get请求方式
			httpClient.doGet(url, map);
			//Post请求方式
			map.put("ip", IPStr);
			httpClient.doPost(url, map);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

测试类中IP请自行填写测试,为了隐私就不暴露具体坐标了。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值