HttpClient详细实例,Httoclient调用https实例,避免https SSL认证

   最近公司将原有的http协议接口,更改为了可支持https的双向接口,在查阅资料同时,将解决过程与大家分享。

使用的框架是Struts2,如有变动可自行修改相应代码。


首先,我们看看httpClient是个什么东西,它有什么作用,它能干嘛,它地基本用法?

百度介绍:http://baike.baidu.com/link?url=_gKuBTJc3HqNGmSEoXyVwW0mlUE2joDRWH8SbFzp0KvppAn63bFrNTzJEQkWVbLXQlAb-ermhwoLBORmnH_1Ta

基本使用详情①(转载):http://blog.csdn.net/wangpeng047/article/details/19624529

基本使用详情②(转载):http://blog.csdn.net/5iasp/article/details/8638800  

--以上 基本可以让你对httpClient有个基本了解,也可以有个基本的使用。

httpClient是一个用于调用http协议的插件,要使用此插件需使用以下jar包:

commons-beanutils-1.8.0.jar
commons-codec.jar
commons-collections-3.2.jar
commons-lang-2.4.jar
commons-lang3-3.1.jar
commons-logging-1.1.1.jar
ezmorph-1.0.4.jar
httpclient-4.1.3.jar
httpclient-cache-4.1.3.jar
httpcore-4.1.4.jar
httpmime-4.1.3.jar
json-lib-2.4-jdk15.jar

以上jar下载地址:

http://download.csdn.net/detail/dcb_ripple/9477012

简单的的httpClient 使用,

1.httpClient 简单使用HttpPost调用http接口


import java.util.ArrayList;
	import java.util.List;

	import org.apache.http.HttpResponse;
	import org.apache.http.NameValuePair;
	import org.apache.http.auth.AuthScope;
	import org.apache.http.auth.UsernamePasswordCredentials;
	import org.apache.http.client.CredentialsProvider;
	import org.apache.http.client.HttpClient;
	import org.apache.http.client.entity.UrlEncodedFormEntity;
	import org.apache.http.client.methods.HttpPost;
	import org.apache.http.entity.StringEntity;
	import org.apache.http.impl.client.BasicCredentialsProvider;
	import org.apache.http.impl.client.DefaultHttpClient;
	import org.apache.http.message.BasicNameValuePair;
	import org.apache.http.util.EntityUtils;
	/**
	 * 使用httpPost  http登陆接口(无http摘要认证)
	 */
	public static void testHttpClient(){
		//1.创建httpClient对象 (使用https协议,需要略过ssl验证,这里使用MySSLSocketFactory)
		HttpClient httpclient = new DefaultHttpClient();
		//url https地址    
		String url ="http://192.168.10.215:8080/tnserver/property_manager/login";
        try {
        	//2.创建列参数(httpPost使用)
        	HttpPost httppost = new HttpPost(url);
        	List<NameValuePair> list = new ArrayList<NameValuePair>();
        	//将用户名与密码作为参数写入(username,password这两个参数是   根据你的接口协议而定)
        	list.add(new BasicNameValuePair("username","admin"));
        	list.add(new BasicNameValuePair("password","123456"));
        	//3.写入请求头
        	httppost.addHeader("Content-type", "application/x-www-form-urlencoded"); 
        	//4.将参数写入到httpost中,并设置编码格式为UTF-8
        	UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,"UTF-8");
        	httppost.setEntity(entity);
			//5.执行
        	HttpResponse post= httpclient.execute(httppost);
        	//6.执行完毕,判断返回code码,200为正常
            if (post.getStatusLine().getStatusCode() == 200) {  
            	//7.获取返回json格式数据  注意,这里不能直接转java.lang.String进行强转,
            	String conResult =  EntityUtils.toString(post.getEntity());
            	//8.处理返回数据....(完)
            	JSONObject sobj = new JSONObject();  
                sobj = JSONObject.fromObject(conResult);
                System.out.println(sobj);
            } else {  
               System.out.println("失败....");
            }
        }catch(Exception e){
        	e.printStackTrace();
        }
	}

</pre><p></p><pre>
以上这个例子很中规中矩,没有太多特殊处理的地方。

那如果想象一下,要传入的参数是一个JSON格式的数据呢?

例如在登陆时将用户名与密码已json格式传入,

格式如下:

{

"username":"admin",

"password":"admin"

}

====那这个时候如果再采用

List<NameValuePair> list = new ArrayList<NameValuePair>();list.add(new BasicNameValuePair("username","xxxx"));list.add(new BasicNameValuePair("password","xxxxx"));

的方式传参肯定是有问题的,因为它采用key/value的方式传值方式,与action中   ”getRequest().getParameter(“xxx”)  “ 是一个道理

那么这个时候该怎么进行参数的传递呢?--看下面

2.httpClient 简单使用HttpPost 参数类型为JSON格式时

/**
	 * 使用httpPost 参数为JSON格式时(无http摘要认证)
	 */
	public static void testHttpClient1(){
		
		HttpClient httpclient = new DefaultHttpClient();

		String url ="http://192.168.10.215:8080/tnserver/property_manager/login";
        try {

        	HttpPost httppost = new HttpPost(url);
        	httppost.addHeader("Content-type", "application/x-www-form-urlencoded"); 
        	//此处略有不同的是,它是直接将JSON格式数据写如到httppost.setEntity实体中
        	//并采用了StringEntity工具类,来进行转换。。。。
        	JSONObject json = new JSONObject();
        	json.put("username", "admin@qq.com");
        	json.put("password", "123456");
        	
        	StringEntity entity = new StringEntity(json.toString(),"UTF-8");
        	
        	httppost.setEntity(entity);
        	
        	HttpResponse post= httpclient.execute(httppost);
        
            if (post.getStatusLine().getStatusCode() == 200) {  
            	
            	String conResult =  EntityUtils.toString(post.getEntity());
            	
            	JSONObject sobj = new JSONObject();  
                sobj = JSONObject.fromObject(conResult);
                System.out.println(sobj);
            } else {  
               System.out.println("失败....");
            }
        }catch(Exception e){
        	e.printStackTrace();
        }finally{
        	
        }
	}

 通过上面StringEntity entity 类的处理就可以实现传输JSON格式参数了。 

是不是很简单,快试一试就知道了,上面的代码只需要Copy到自己的Main方法中就可以测试。。。。。  

不过要注意测试之前请先弄清楚你的htpp接口根据接口进行相应更改

===========================================================

以上两个例子只可基于http协议,且服务器中没有设置身份认证的情况下。。。

服务器中有账户认证处理

具体如下:

public static void testHttpClient2(){
		
		HttpClient httpclient = new DefaultHttpClient();

		String url ="http://xxxxx:xxxxx/tnserver/property_manager/login";
        try {

        	HttpPost httppost = new HttpPost(url);
        	
        	//==========http认证过程===================== 如无需采用https协议进行调用,可忽略https认证过程
        	//注:此方法只用于import org.apache.http.client.HttpClient; 新版本的认证
        	
        	//旧版本:import org.apache.commons.httpclient 认证方法如下:
        	//Credentials defaultcreds = new UsernamePasswordCredentials("userxxx","pwdxxx");
        	//httpClient.getState().setCredentials(AuthScope.ANY, defaultcreds);
        	//注意。 旧版本的认证方式导入的包是 带 org.apache.commons.xxxx
        	
        	//创建https认证对象  
        	CredentialsProvider credsProvider = new BasicCredentialsProvider();
        	//写入认证的用户名与密码
        	UsernamePasswordCredentials creds = new UsernamePasswordCredentials("xxx", "xxx"); 
        	//创建验证  
             credsProvider.setCredentials(  
                 new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),   
                 creds);
             //将认证写入到httpClient中  
             ((DefaultHttpClient)httpclient).setCredentialsProvider(credsProvider);   
             //=========Https认证===end=============================
            
        	httppost.addHeader("Content-type", "application/x-www-form-urlencoded"); 
        	
        	JSONObject json = new JSONObject();
        	json.put("username", "xxxx");
        	json.put("password", "xxxxx");
        	StringEntity entity = new StringEntity(json.toString());
        
        	httppost.setEntity(entity);
 
        	HttpResponse post= httpclient.execute(httppost);

            if (post.getStatusLine().getStatusCode() == 200) {  
            

            	String conResult =  EntityUtils.toString(post.getEntity());

            	JSONObject sobj = new JSONObject();  
                sobj = JSONObject.fromObject(conResult);
                System.out.println(sobj);
            } else {  
               System.out.println("失败....");
            }
        }catch(Exception e){
        	e.printStackTrace();
        }finally{
        	
        }
	}
这个认证账户密码是在http服务器中设置,所以别说不知账户密码是什么,直接问接口提供方。
前提是对方告诉你这是一个基于http协议的接口,并且会有认证过程。


好,上面说了又一种旧版本的认证方式,这里直接附上 (注意这里的调用方式不一样,旧版本没有httpPost 而是PostMethod。。详情请百度。

http://www.cnblogs.com/davidwang456/p/4062233.html


HTTPS如果略过证书认证过程

那又如果使用是基于HTTPS的呢? 

HTTPS与HTTP有很大区别,它相比HTTP协议更安全,更高效。

HTTP与HTTP区别:http://blog.csdn.net/angussl/article/details/5557738

-正题:如何在调用时略过HTTPS 证书SSL认证过程

在调用https协议的的接口时都会遇到一个问题,那就是SSL证书怎么破,难道真的在本地安装?貌似有点不好弄,说实话我也不会.....

所以我们肯定是希望有这么一个东西,那就是可以在使用的时候忽略SSL认证的问题,那么这样我们就不必为SSL而苦恼。


代码:

package com.httpclicent;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
/**
 * https SSL证书避免认证问题 (注意此处同样是新版本的SSL避免方式)
 * @author yzs
 *
 */
public class MySSLSocketFactory extends SSLSocketFactory {
	
    SSLContext sslContext = SSLContext.getInstance("TLS");
    
    /**
     * 
     * @param truststore
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @throws KeyStoreException
     * @throws UnrecoverableKeyException
     */
    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sslContext.init(null, new TrustManager[] { tm }, null);
    }
    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }
    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }
    
    /**
     * 在使用时直接调用它即可,,,, 直接得略过https的ssl验证过程  
     * @return
     */
    public static HttpClient getNewHttpClient() {
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

            return new DefaultHttpClient(ccm, params);
        } catch (Exception e) {
            return new DefaultHttpClient();
        }
    }
}

=============================说明:此类是从别处找到,并非自己写出来的

有了这个Class一切都将不是问题,无需太大改动,只需要在创建HttpClicent时 使用 类中的getNewHttpClient即可

如下:

//1.创建httpClient对象 (使用https协议,需要略过ssl验证,这里使用MySSLSocketFactory)

HttpClient httpclient = MySSLSocketFactory.getNewHttpClient();


代码:


public static void testHttpClient3(){
		
		
		//1.创建httpClient对象 (使用https协议,需要略过ssl验证,这里使用MySSLSocketFactory)
		HttpClient httpclient = MySSLSocketFactory.getNewHttpClient();
<span style="white-space:pre">		</span>//http默认端口号是80  https为443  
		String url ="http://xxxx:443/tnserver/property_manager/login";
        try {

        	HttpPost httppost = new HttpPost(url);
        	
        	//==========https认证过程===================== 如无需采用https协议进行调用,客户了https认证过程
        	//注:此方法只用于import org.apache.http.client.HttpClient; 新版本的认证
        	
        	
        	//创建https认证对象  
        	CredentialsProvider credsProvider = new BasicCredentialsProvider();
        	//写入认证的用户名与密码
        	UsernamePasswordCredentials creds = new UsernamePasswordCredentials("xxx", "xxx"); 
        	//创建验证  
             credsProvider.setCredentials(  
                 new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),   
                 creds);
             //将认证写入到httpClient中  
             ((DefaultHttpClient)httpclient).setCredentialsProvider(credsProvider);   
             //=========Https认证===end=============================
            
        	httppost.addHeader("Content-type", "application/x-www-form-urlencoded"); 
        	
        	JSONObject json = new JSONObject();
        	json.put("username", "xxx");
        	json.put("password", "xxx");
        	StringEntity entity = new StringEntity(json.toString());
        
        	httppost.setEntity(entity);
 
        	HttpResponse post= httpclient.execute(httppost);

            if (post.getStatusLine().getStatusCode() == 200) {  
            

            	String conResult =  EntityUtils.toString(post.getEntity());

            	JSONObject sobj = new JSONObject();  
                sobj = JSONObject.fromObject(conResult);
                System.out.println(sobj);
            } else {  
               System.out.println("失败....");
            }
        }catch(Exception e){
        	e.printStackTrace();
        }finally{
        	
        }
	}


ok,有以上代码基本可以实现大部分http与https接口的调用了。。。。

附上一个自己项目中实际使用的实例

需求:



代码实现Action:

package cn.thinknet.action;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import cn.thinknet.bean.UserManage;
import cn.thinknet.util.MySSLSocketFactory;
public class UserManageAction extends BaseAction{
	
	private String msg;
	private List<UserManage> userManageList;
	private JSONArray resultJa;
	private String ids;
	private JSONObject result;
	private UserManage userManage;
	
	public String login(){
		
		//1.创建httpClient对象 (使用https协议,需要略过ssl验证,这里使用MySSLSocketFactory)
		
		//注:如无需使用https协议进行调用,则代码创建处理如下
		// HttpClient httpclient1 = new DefaultHttpClient();
		HttpClient httpclient = MySSLSocketFactory.getNewHttpClient();
		
		//url https地址
		String url ="https://192.168.10.216:443/tnserver/property_manager/login";
        try {
        	//2.创建列参数(httpPost使用)
        	List<NameValuePair> list = new ArrayList<NameValuePair>();
        	//将用户名与密码作为参数写入(username,password这两个参数是   根据你的接口协议而定)
        	list.add(new BasicNameValuePair("username","admin@163.com"));
        	list.add(new BasicNameValuePair("password","123456"));
        	//3.创建http对象 
        	HttpPost httppost = new HttpPost(url);
        	//==========https认证过程===================== 如无需采用https协议进行调用,客户了https认证过程
        	//注:此方法只用于import org.apache.http.client.HttpClient; 新版本的认证
        	
        	//旧版本:import org.apache.commons.httpclient 认证方法如下:
        	//Credentials defaultcreds = new UsernamePasswordCredentials("userxxx","pwdxxx");
        	//httpClient.getState().setCredentials(AuthScope.ANY, defaultcreds);
        	//注意。 旧版本的认证方式导入的包是 带 org.apache.commons.xxxx
        	
        	//创建https认证对象  
        	CredentialsProvider credsProvider = new BasicCredentialsProvider();
        	//写入认证的用户名与密码
        	UsernamePasswordCredentials creds = new UsernamePasswordCredentials("admin", "123"); 
        	//创建验证  
             credsProvider.setCredentials(  
                 new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),   
                 creds);
             //将认证写入到httpClient中  
             ((DefaultHttpClient)httpclient).setCredentialsProvider(credsProvider);   
             //============end=============================
            
        	httppost.addHeader("Content-type", "application/x-www-form-urlencoded"); 
        	//4.将参数写入到httpost中,并设置编码格式为UTF-8
        	UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,"UTF-8");
        	httppost.setEntity(entity);
        	//5.执行
        	HttpResponse post= httpclient.execute(httppost);
        	//6.执行完毕,判断返回code码,200为正常
            if (post.getStatusLine().getStatusCode() == 200) {  
            
            	//7.获取返回json格式数据  注意,这里不能直接转java.lang.String进行强转,
            	String conResult =  EntityUtils.toString(post.getEntity());
            	//8.处理返回数据....(完)
            	JSONObject sobj = new JSONObject();  
                sobj = JSONObject.fromObject(conResult);
                System.out.println(sobj);
            } else {  
               System.out.println("失败....");
            }
        }catch(Exception e){
        	e.printStackTrace();
        }finally{
        	
        }
        return "success1";
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public JSONArray getResultJa() {
		return resultJa;
	}

	public void setResultJa(JSONArray resultJa) {
		this.resultJa = resultJa;
	}

	public JSONObject getResult() {
		return result;
	}

	public void setResult(JSONObject result) {
		this.result = result;
	}

	public String getIds() {
		return ids;
	}

	public void setIds(String ids) {
		this.ids = ids;
	}

	public UserManage getUserManage() {
		return userManage;
	}

	public void setUserManage(UserManage userManage) {
		this.userManage = userManage;
	}

	public List<UserManage> getUserManageList() {
		return userManageList;
	}

	public void setUserManageList(List<UserManage> userManageList) {
		this.userManageList = userManageList;
	}

}

返回结果:



======




完成!!! 没了,就这么多啦~~~

本人目前也是属于java两年新人,勿喷~~

最后附上简单Dome:

http://download.csdn.net/detail/dcb_ripple/9477041



  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值