HttpClient的get和post

HttpClient的get和post

这个HttpClient就类似于电脑上用的浏览器。当我打开多个网页的时候,并不需要开一个网页就开一个浏览器,而是一个浏览器上面开了好几个网页。对应于HttpClient,即无需连接一次就new一个HttpClient。一般,我们希望一个应用里就一个HttpClient就ok了,就像我们的手机或PC,没人会呼呼的装好几个浏览器。本文即解决此问题,代码可以直接拿过去复用。

1.自然而然想到单例。

public class MyHttpClient {
private static HttpClient mHttpClient = null;
private static final String CHARSET = HTTP.UTF_8;
//将构造函数封掉,只能通过对外接口来获取HttpClient实例
private MyHttpClient(){
}
public static HttpClient getHttpClient(){
    if(mHttpClient == null){
        mHttpClient = new DefaultHttpClient();
    }
    return mHttpClient;
    }
}

上面很簡單但是不能满足多线程的要求,不能同时完成多个Http请求时。

2.线程安全的HttpClient
可以创建线程安全的HttpClient,即通过ClientConnectionManager 来完成。下面贴出完整代码:

import org.apache.http.HttpVersion;  
import org.apache.http.client.HttpClient;  
import org.apache.http.conn.ClientConnectionManager;  
import org.apache.http.conn.params.ConnManagerParams;  
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.HttpConnectionParams;  
import org.apache.http.params.HttpParams;  
import org.apache.http.params.HttpProtocolParams;  
import org.apache.http.protocol.HTTP;  

public class MyHttpClient {  
    private static HttpClient mHttpClient = null;  
    private static final String CHARSET = HTTP.UTF_8;  
    //将构造函数封掉,只能通过对外接口来获取HttpClient实例  
    private MyHttpClient(){  

    }  
    public static HttpClient getHttpClient(){  
        if(mHttpClient == null){  
            mHttpClient = new DefaultHttpClient();  
        }  
        return mHttpClient;  
    }  
    public static synchronized HttpClient getSaveHttpClient(){  
        if(mHttpClient == null){  
            HttpParams params = new BasicHttpParams();  
            //设置基本参数  
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);  
            HttpProtocolParams.setContentCharset(params, CHARSET);  
            HttpProtocolParams.setUseExpectContinue(params, true);  
            //超时设置  
            /*从连接池中取连接的超时时间*/  
            ConnManagerParams.setTimeout(params, 1000);  
            /*连接超时*/  
            HttpConnectionParams.setConnectionTimeout(params, 2000);  
            /*请求超时*/  
            HttpConnectionParams.setSoTimeout(params, 4000);  
            //设置HttpClient支持HTTp和HTTPS两种模式  
            SchemeRegistry schReg = new SchemeRegistry();  
            schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));  
            schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));  
            //使用线程安全的连接管理来创建HttpClient  
            ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);  
            mHttpClient = new DefaultHttpClient(conMgr, params);  
        }  
        return mHttpClient;  
    }  

}  

方法getSaveHttpClient()即可获得线程安全的单例httpClient,注释很详细了啥都不说了,可以直接使用。

3、已经很完美了,还能不能再优化呢?
可以使用Application来进一步优化创建HttpClient的时机及其他配置。Application的相关知识参见:链接
新建包名org.yanzi.application,在里面新建MyApplication.java,完整代码如下:

import org.apache.http.HttpVersion;  
import org.apache.http.client.HttpClient;  
import org.apache.http.conn.ClientConnectionManager;  
import org.apache.http.conn.params.ConnManagerParams;  
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.HttpConnectionParams;  
import org.apache.http.params.HttpParams;  
import org.apache.http.params.HttpProtocolParams;  
import org.apache.http.protocol.HTTP;  

import android.app.Application;  

public class MyApplication extends Application {  
    private HttpClient mHttpClient = null;  
    private static final String CHARSET = HTTP.UTF_8;  
    @Override  
    public void onCreate() {  
        // TODO Auto-generated method stub  
        super.onCreate();  
        mHttpClient = this.createHttpClient();  
    } 
     @Override  
    public void onTerminate() {  
        // TODO Auto-generated method stub  
        super.onTerminate();  
        this.shutdownHttpClient();  
    }  

    @Override  
    public void onLowMemory() {  
        // TODO Auto-generated method stub  
        super.onLowMemory();  
        this.shutdownHttpClient();  
    }  

    /**创建HttpClient实例 
     * @return 
     */  
    private HttpClient createHttpClient(){  
        HttpParams params = new BasicHttpParams();  
        //设置基本参数  
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);  
        HttpProtocolParams.setContentCharset(params, CHARSET);  
        HttpProtocolParams.setUseExpectContinue(params, true);  
        //超时设置  
        /*从连接池中取连接的超时时间*/  
        ConnManagerParams.setTimeout(params, 1000);  
        /*连接超时*/  
        HttpConnectionParams.setConnectionTimeout(params, 2000);  
        /*请求超时*/  
        HttpConnectionParams.setSoTimeout(params, 4000);  
        //设置HttpClient支持HTTp和HTTPS两种模式  
        SchemeRegistry schReg = new SchemeRegistry();  
        schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));  
        schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));  
        //使用线程安全的连接管理来创建HttpClient  
        ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);  
        HttpClient client = new DefaultHttpClient(conMgr, params);  
        return client;  
    }  
    private void shutdownHttpClient(){  
        if(mHttpClient != null && mHttpClient.getConnectionManager() != null){  
            mHttpClient.getConnectionManager().shutdown();  
        }  
    }  
    public HttpClient getHttpClient(){  
        return mHttpClient;  
    }  

}   

然后再AndroidManifest.xml理添加:
android:name=”org.yanzi.application.MyApplication”

<application  
        android:name="org.yanzi.application.MyApplication"  
        android:allowBackup="true"  
        android:icon="@drawable/ic_launcher"  
        android:label="@string/app_name"  
        android:theme="@style/AppTheme" >  
        <activity  
            android:name="org.yanzi.testtomecat.MainActivity"  
            android:label="@string/app_name" >  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />  

                <category android:name="android.intent.category.LAUNCHER" />  
            </intent-filter>  
        </activity>  
    </application>

然后再Activity里,通过mMyApplication = (MyApplication)getApplication();
mMyApplication.getHttpClient()得到HttpClient就可以使用了。
可以看到在Application的onCreate里就实例化了HttpClient,且在低内存和关闭时关闭连接管理器,释放资源,比2中的写到一个普通文件里更优。

import java.io.IOException;  
import java.util.List;  

import org.apache.http.HttpResponse;  
import org.apache.http.HttpStatus;  
import org.apache.http.NameValuePair;  
import org.apache.http.client.ClientProtocolException;  
import org.apache.http.client.HttpClient;  
import org.apache.http.client.entity.UrlEncodedFormEntity;  
import org.apache.http.client.methods.HttpGet;  
import org.apache.http.client.methods.HttpPost;  
import org.apache.http.impl.client.DefaultHttpClient;  
import org.apache.http.params.BasicHttpParams;  
import org.apache.http.params.HttpConnectionParams;  
import org.apache.http.params.HttpParams;  

import android.util.Log;  

public class HttpRequest {  
    /** 
     *Post请求 
     */  
    public void doPost(String url , List<NameValuePair> nameValuePairs){  
        //新建HttpClient对象    
        HttpClient httpclient = new DefaultHttpClient();  
        //创建POST连接  
        HttpPost httppost = new HttpPost(url);  
        try {  
//          //使用PSOT方式,必须用NameValuePair数组传递参数  
//          List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();  
//          nameValuePairs.add(new BasicNameValuePair("id", "12345"));  
//          nameValuePairs.add(new BasicNameValuePair("stringdata","hps is Cool!"));  
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));  
            HttpResponse response = httpclient.execute(httppost);  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  

    /** 
     *Get请求 
     */  
    public void doGet(String url){  
        HttpParams httpParams = new BasicHttpParams();  
        HttpConnectionParams.setConnectionTimeout(httpParams,30000);    
        HttpConnectionParams.setSoTimeout(httpParams, 30000);    

        HttpClient httpClient = new DefaultHttpClient(httpParams);    
        // GET  
        HttpGet httpGet = new HttpGet(url);  
        try {  
            HttpResponse response = httpClient.execute(httpGet);  
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){  
                Log.i("GET", "Bad Request!");  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  

    }  
}  

需要注意的是:
1. 使用POST方式时,传递参数必须使用NameValuePair数组
2. 使用GET方式时,通过URL传递参数,注意写法
3. 通过setEntity方法来传递数据
4. 通过DefaultHttpClient的execute方法来发送HTTP请求获取HttpResponse
5. 通过getEntity()从Response中获取内容

String content = EntityUtils.toString(response.getEntity());

特别说明:
对于WCF的json服务,请求时如下:

/**  
     *Post请求  
     * @throws IOException  
     * @throws ClientProtocolException  
     */    
    public static String doPost(String url , List<NameValuePair> nameValuePairs) throws ClientProtocolException, IOException{   
        String result = null;  
        //新建HttpClient对象      
        HttpClient httpclient = new DefaultHttpClient();    
        //创建POST连接    
        HttpPost httppost = new HttpPost(url);    
        httppost.setHeader("content-type", "application/json");  
        try {  
            if(nameValuePairs != null) {  
                StringEntity entity = new StringEntity("这里是JSON数据,如{"id":"12","name":"xiaoming"}", "utf-8");  
                entity.setContentType("application/json");  
                entity.setContentEncoding("utf-8");  
                httppost.setEntity(entity);  
            }  

//          if(nameValuePairs != null) {  
//              httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));    
//          }  
            HttpResponse response = httpclient.execute(httppost);    
            if (response.getStatusLine().getStatusCode() != 404)  
            {  
                    result = EntityUtils.toString(response.getEntity());  
                    Logger.d(TAG, "Response: " + result);  
            }  
        } finally {  

        }  
        return result;  
    }  

其实就相当于传数据流的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值