Android應用層(網絡編程)二(HttpClient、HttpURLConnection)

HttpClient與HttpURLConnection

1.HttpClient

Android SDK中包含了HttpClient,在Android6.0版本直接刪除了HttpClient類庫,如果仍想使用則解決方法是:
- 如果使用的是eclipse則在libs中加入org.apache.http.legacy.jar這個jar包在:**sdk\platforms\android-23\optional目錄中(需要下載android
6.0的SDK)
- 如果使用的是android studio則 在相應的module下的build.gradle中加入:

android {
    useLibrary 'org.apache.http.legacy'
     }

1.1 HttpClient的GET請求

Step 1 : 用DefaultHttpClient類來實例化一個HttpClient,並配置好默認的請求參數

//創建HttpClient
   private HttpClient createHttpClient() {
       HttpParams mDefaultHttpParams = new BasicHttpParams();
       //設置連接超時
       HttpConnectionParams.setConnectionTimeout(mDefaultHttpParams, 15000);
       //設置請求超時
       HttpConnectionParams.setSoTimeout(mDefaultHttpParams, 15000);
       HttpConnectionParams.setTcpNoDelay(mDefaultHttpParams, true);
       HttpProtocolParams.setVersion(mDefaultHttpParams, HttpVersion.HTTP_1_1);
       HttpProtocolParams.setContentCharset(mDefaultHttpParams, HTTP.UTF_8);
       //持續握手
       HttpProtocolParams.setUseExpectContinue(mDefaultHttpParams, true);
       HttpClient mHttpClient = new DefaultHttpClient(mDefaultHttpParams);
       return mHttpClient;
   }

Step 2 : 創建HttpGet和HttpClient,請求網絡並得到HttpResponse,並對HttpResponse進行處理

private void useHttpClientGet(String url) {
      HttpGet mHttpGet = new HttpGet(url);
      mHttpGet.addHeader("Connection", "Keep-Alive");
      try {
          HttpClient mHttpClient = createHttpClient();
          HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
          HttpEntity mHttpEntity = mHttpResponse.getEntity();
          int code = mHttpResponse.getStatusLine().getStatusCode();
          if (null != mHttpEntity) {
              InputStream mInputStream = mHttpEntity.getContent();
              String respose = converStreamToString(mInputStream);
              Log.i("wangshu", "請求狀態碼:" + code + "\n請求結果:\n" + respose);
              mInputStream.close();
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

converStreamToString方法將請求結果轉換成String類型:

private String converStreamToString(InputStream is) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuffer sb = new StringBuffer();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        String respose = sb.toString();
        return respose;
    }

最後我們開啓線程訪問百度:

new Thread(new Runnable() {
          @Override
          public void run() {
              useHttpClientGet("http://www.baidu.com");
          }
      }).start();

1.2 HttpClient的POST請求

post請求和get類似,就是需要配置要傳遞的參數:

private void useHttpClientPost(String url) {
    HttpPost mHttpPost = new HttpPost(url);
    mHttpPost.addHeader("Connection", "Keep-Alive");
    try {
        HttpClient mHttpClient = createHttpClient();
        List<NameValuePair> postParams = new ArrayList<>();
        //要傳遞的參數
        postParams.add(new BasicNameValuePair("username", "moon"));
        postParams.add(new BasicNameValuePair("password", "123"));
        mHttpPost.setEntity(new UrlEncodedFormEntity(postParams));
        HttpResponse mHttpResponse = mHttpClient.execute(mHttpPost);
        HttpEntity mHttpEntity = mHttpResponse.getEntity();
        int code = mHttpResponse.getStatusLine().getStatusCode();
        if (null != mHttpEntity) {
            InputStream mInputStream = mHttpEntity.getContent();
            String respose = converStreamToString(mInputStream);
            Log.i("wangshu", "請求狀態碼:" + code + "\n請求結果:\n" + respose);
            mInputStream.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2. HttpURLConnection

它的API簡單,體積較小,因而非常適用於Android項目。壓縮和緩存機制可以有效地減少網絡訪問的流量,在提升速度和省電方面也起到了較大的作用。另外在Android 6.0版本中,HttpClient庫被移除了,HttpURLConnection則是以後我們唯一的選擇。

2.1 HttpURLConnection的POST請求

Step 1 : 創建一個UrlConnManager類,提供getHttpURLConnection()方法用於配置默認的參數並返回HttpURLConnection

public static HttpURLConnection getHttpURLConnection(String url){
     HttpURLConnection mHttpURLConnection=null;
     try {
         URL mUrl=new URL(url);
         mHttpURLConnection=(HttpURLConnection)mUrl.openConnection();
         //設置鏈接超時時間
         mHttpURLConnection.setConnectTimeout(15000);
         //設置讀取超時時間
         mHttpURLConnection.setReadTimeout(15000);
         //設置請求參數
         mHttpURLConnection.setRequestMethod("POST");
         //添加Header
         mHttpURLConnection.setRequestProperty("Connection","Keep-Alive");
         //接收輸入流
         mHttpURLConnection.setDoInput(true);
         //傳遞參數時需要開啓
         mHttpURLConnection.setDoOutput(true);
     } catch (IOException e) {
         e.printStackTrace();
     }
     return mHttpURLConnection ;
 }
 ```
#### Step 2 : 在UrlConnManager類中再寫一個postParams()方法用來組織一下請求參數並將請求參數寫入到輸出流中
 ```
 public static void postParams(OutputStream output,List<NameValuePair>paramsList) throws IOException{
      StringBuilder mStringBuilder=new StringBuilder();
      for (NameValuePair pair:paramsList){
          if(!TextUtils.isEmpty(mStringBuilder)){
              mStringBuilder.append("&");
          }
          mStringBuilder.append(URLEncoder.encode(pair.getName(),"UTF-8"));
          mStringBuilder.append("=");
          mStringBuilder.append(URLEncoder.encode(pair.getValue(),"UTF-8"));
      }
      BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));
      writer.write(mStringBuilder.toString());
      writer.flush();
      writer.close();
  }

Step 3 : 添加請求參數,調用postParams()方法將請求的參數組織好傳給HttpURLConnection的輸出流,請求連接並處理返回的結果

private void useHttpUrlConnectionPost(String url) {
     InputStream mInputStream = null;
     HttpURLConnection mHttpURLConnection = UrlConnManager.getHttpURLConnection(url);
     try {
         List<NameValuePair> postParams = new ArrayList<>();
         //要傳遞的參數
         postParams.add(new BasicNameValuePair("username", "moon"));
         postParams.add(new BasicNameValuePair("password", "123"));
         UrlConnManager.postParams(mHttpURLConnection.getOutputStream(), postParams);
         mHttpURLConnection.connect();
         mInputStream = mHttpURLConnection.getInputStream();
         int code = mHttpURLConnection.getResponseCode();
         String respose = converStreamToString(mInputStream);
         Log.i("wangshu", "請求狀態碼:" + code + "\n請求結果:\n" + respose);
         mInputStream.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
 }

Step 4 : 開啓線程請求網絡

private void useHttpUrlConnectionGetThread() {
       new Thread(new Runnable() {
           @Override
           public void run() {
               useHttpUrlConnectionPost("http://www.baidu.com");
           }
       }).start();
   }

報504錯誤,讀取響應的數據報錯,對於我們這次請求服務端不能返回完整的響應,返回的數據爲0 bytes,所以mHttpURLConnection.getInputStream() 也讀不到服務端響應的輸入流。當然這次錯誤是正常的,百度沒理由處理我們的這次POST請求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章