天天看點

Java:使用HttpClient進行POST和GET請求以及檔案上傳和下載下傳

1.HttpClient

大家可以先看一下HttpClient的介紹,這篇博文寫的還算不錯​

當然,詳細的文檔,你可以去官方網站檢視和下載下傳:​​http://hc.apache.org/httpclient-3.x/​​

2.本部落格簡單介紹一下POST和GET以及檔案下載下傳的應用。

代碼如下:

package net.mobctrl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

/**
 * @web http://www.mobctrl.net
 * @author Zheng Haibo
 * @Description: 檔案下載下傳 POST GET
 */
public class HttpClientUtils {

  /**
   * 最大線程池
   */
  public static final int THREAD_POOL_SIZE = 5;

  public interface HttpClientDownLoadProgress {
    public void onProgress(int progress);
  }

  private static HttpClientUtils httpClientDownload;

  private ExecutorService downloadExcutorService;

  private HttpClientUtils() {
    downloadExcutorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
  }

  public static HttpClientUtils getInstance() {
    if (httpClientDownload == null) {
      httpClientDownload = new HttpClientUtils();
    }
    return httpClientDownload;
  }

  /**
   * 下載下傳檔案
   * 
   * @param url
   * @param filePath
   */
  public void download(final String url, final String filePath) {
    downloadExcutorService.execute(new Runnable() {

      @Override
      public void run() {
        httpDownloadFile(url, filePath, null, null);
      }
    });
  }

  /**
   * 下載下傳檔案
   * 
   * @param url
   * @param filePath
   * @param progress
   *            進度回調
   */
  public void download(final String url, final String filePath,
      final HttpClientDownLoadProgress progress) {
    downloadExcutorService.execute(new Runnable() {

      @Override
      public void run() {
        httpDownloadFile(url, filePath, progress, null);
      }
    });
  }

  /**
   * 下載下傳檔案
   * 
   * @param url
   * @param filePath
   */
  private void httpDownloadFile(String url, String filePath,
      HttpClientDownLoadProgress progress, Map<String, String> headMap) {
    CloseableHttpClient httpclient = HttpClients.createDefault();
    try {
      HttpGet httpGet = new HttpGet(url);
      setGetHead(httpGet, headMap);
      CloseableHttpResponse response1 = httpclient.execute(httpGet);
      try {
        System.out.println(response1.getStatusLine());
        HttpEntity httpEntity = response1.getEntity();
        long contentLength = httpEntity.getContentLength();
        InputStream is = httpEntity.getContent();
        // 根據InputStream 下載下傳檔案
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int r = 0;
        long totalRead = 0;
        while ((r = is.read(buffer)) > 0) {
          output.write(buffer, 0, r);
          totalRead += r;
          if (progress != null) {// 回調進度
            progress.onProgress((int) (totalRead * 100 / contentLength));
          }
        }
        FileOutputStream fos = new FileOutputStream(filePath);
        output.writeTo(fos);
        output.flush();
        output.close();
        fos.close();
        EntityUtils.consume(httpEntity);
      } finally {
        response1.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        httpclient.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * get請求
   * 
   * @param url
   * @return
   */
  public String httpGet(String url) {
    return httpGet(url, null);
  }

  /**
   * http get請求
   * 
   * @param url
   * @return
   */
  public String httpGet(String url, Map<String, String> headMap) {
    String responseContent = null;
    CloseableHttpClient httpclient = HttpClients.createDefault();
    try {
      HttpGet httpGet = new HttpGet(url);
      CloseableHttpResponse response1 = httpclient.execute(httpGet);
      setGetHead(httpGet, headMap);
      try {
        System.out.println(response1.getStatusLine());
        HttpEntity entity = response1.getEntity();
        responseContent = getRespString(entity);
        System.out.println("debug:" + responseContent);
        EntityUtils.consume(entity);
      } finally {
        response1.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        httpclient.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return responseContent;
  }

  public String httpPost(String url, Map<String, String> paramsMap) {
    return httpPost(url, paramsMap, null);
  }

  /**
   * http的post請求
   * 
   * @param url
   * @param paramsMap
   * @return
   */
  public String httpPost(String url, Map<String, String> paramsMap,
      Map<String, String> headMap) {
    String responseContent = null;
    CloseableHttpClient httpclient = HttpClients.createDefault();
    try {
      HttpPost httpPost = new HttpPost(url);
      setPostHead(httpPost, headMap);
      setPostParams(httpPost, paramsMap);
      CloseableHttpResponse response = httpclient.execute(httpPost);
      try {
        System.out.println(response.getStatusLine());
        HttpEntity entity = response.getEntity();
        responseContent = getRespString(entity);
        EntityUtils.consume(entity);
      } finally {
        response.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        httpclient.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    System.out.println("responseContent = " + responseContent);
    return responseContent;
  }

  /**
   * 設定POST的參數
   * 
   * @param httpPost
   * @param paramsMap
   * @throws Exception
   */
  private void setPostParams(HttpPost httpPost, Map<String, String> paramsMap)
      throws Exception {
    if (paramsMap != null && paramsMap.size() > 0) {
      List<NameValuePair> nvps = new ArrayList<NameValuePair>();
      Set<String> keySet = paramsMap.keySet();
      for (String key : keySet) {
        nvps.add(new BasicNameValuePair(key, paramsMap.get(key)));
      }
      httpPost.setEntity(new UrlEncodedFormEntity(nvps));
    }
  }

  /**
   * 設定http的HEAD
   * 
   * @param httpPost
   * @param headMap
   */
  private void setPostHead(HttpPost httpPost, Map<String, String> headMap) {
    if (headMap != null && headMap.size() > 0) {
      Set<String> keySet = headMap.keySet();
      for (String key : keySet) {
        httpPost.addHeader(key, headMap.get(key));
      }
    }
  }

  /**
   * 設定http的HEAD
   * 
   * @param httpGet
   * @param headMap
   */
  private void setGetHead(HttpGet httpGet, Map<String, String> headMap) {
    if (headMap != null && headMap.size() > 0) {
      Set<String> keySet = headMap.keySet();
      for (String key : keySet) {
        httpGet.addHeader(key, headMap.get(key));
      }
    }
  }

  /**
   * 上傳檔案
   * 
   * @param serverUrl
   *            伺服器位址
   * @param localFilePath
   *            本地檔案路徑
   * @param serverFieldName
   * @param params
   * @return
   * @throws Exception
   */
  public String uploadFileImpl(String serverUrl, String localFilePath,
      String serverFieldName, Map<String, String> params)
      throws Exception {
    String respStr = null;
    CloseableHttpClient httpclient = HttpClients.createDefault();
    try {
      HttpPost httppost = new HttpPost(serverUrl);
      FileBody binFileBody = new FileBody(new File(localFilePath));

      MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder
          .create();
      // add the file params
      multipartEntityBuilder.addPart(serverFieldName, binFileBody);
      // 設定上傳的其他參數
      setUploadParams(multipartEntityBuilder, params);

      HttpEntity reqEntity = multipartEntityBuilder.build();
      httppost.setEntity(reqEntity);

      CloseableHttpResponse response = httpclient.execute(httppost);
      try {
        System.out.println(response.getStatusLine());
        HttpEntity resEntity = response.getEntity();
        respStr = getRespString(resEntity);
        EntityUtils.consume(resEntity);
      } finally {
        response.close();
      }
    } finally {
      httpclient.close();
    }
    System.out.println("resp=" + respStr);
    return respStr;
  }

  /**
   * 設定上傳檔案時所附帶的其他參數
   * 
   * @param multipartEntityBuilder
   * @param params
   */
  private void setUploadParams(MultipartEntityBuilder multipartEntityBuilder,
      Map<String, String> params) {
    if (params != null && params.size() > 0) {
      Set<String> keys = params.keySet();
      for (String key : keys) {
        multipartEntityBuilder
            .addPart(key, new StringBody(params.get(key),
                ContentType.TEXT_PLAIN));
      }
    }
  }

  /**
   * 将傳回結果轉化為String
   * 
   * @param entity
   * @return
   * @throws Exception
   */
  private String getRespString(HttpEntity entity) throws Exception {
    if (entity == null) {
      return null;
    }
    InputStream is = entity.getContent();
    StringBuffer strBuf = new StringBuffer();
    byte[] buffer = new byte[4096];
    int r = 0;
    while ((r = is.read(buffer)) > 0) {
      strBuf.append(new String(buffer, 0, r, "UTF-8"));
    }
    return strBuf.toString();
  }
}      

我們可以使用如下代碼進行測試:

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import net.mobctrl.HttpClientUtils;
import net.mobctrl.HttpClientUtils.HttpClientDownLoadProgress;

/**
 * @date 2015年1月14日 下午1:49:50
 * @author Zheng Haibo
 * @Description: 測試
 */
public class Main {

  public static void main(String[] args) {
    /**
     * 測試下載下傳檔案 異步下載下傳
     */
    HttpClientUtils.getInstance().download(
        "http://newbbs.qiniudn.com/phone.png", "test.png",
        new HttpClientDownLoadProgress() {

          @Override
          public void onProgress(int progress) {
            System.out.println("download progress = " + progress);
          }
        });

    // POST 同步方法
    Map<String, String> params = new HashMap<String, String>();
    params.put("username", "admin");
    params.put("password", "admin");
    HttpClientUtils.getInstance().httpPost(
        "http://192.168.31.183:8080/SSHMySql/register", params);

    // GET 同步方法
    HttpClientUtils.getInstance().httpGet(
        "http://wthrcdn.etouch.cn/weather_mini?city=北京");

    // 上傳檔案 POST 同步方法
    try {
      Map<String,String> uploadParams = new LinkedHashMap<String, String>();
      uploadParams.put("userImageContentType", "image");
      uploadParams.put("userImageFileName", "testaa.png");
      HttpClientUtils.getInstance().uploadFileImpl(
          "http://192.168.31.183:8080/SSHMySql/upload", "android_bug_1.png",
          "userImage", uploadParams);
    } catch (Exception e) {
      e.printStackTrace();
    }

  }

}      

運作結果為:

HTTP/1.1 200 OK
responseContent = {"id":"-2","msg":"添加失敗!使用者名已經存在!"}
HTTP/1.1 200 OK
download progress = 6
download progress = 11
download progress = 13
download progress = 20
download progress = 22
download progress = 26
download progress = 31
download progress = 33
download progress = 35
download progress = 38
download progress = 40
download progress = 42
download progress = 44
download progress = 49
download progress = 53
download progress = 55
download progress = 57
download progress = 60
download progress = 62
download progress = 64
download progress = 66
download progress = 71
download progress = 77
download progress = 77
download progress = 80
download progress = 82
HTTP/1.1 200 OK
debug:{"desc":"OK","status":1000,"data":{"wendu":"3","ganmao":"晝夜溫差很大,易發生感冒,請注意适當增減衣服,加強自我防護避免感冒。","forecast":[{"fengxiang":"無持續風向","fengli":"微風級","high":"高溫 6℃","type":"晴","low":"低溫 -6℃","date":"22日星期四"},{"fengxiang":"無持續風向","fengli":"微風級","high":"高溫 6℃","type":"多雲","low":"低溫 -3℃","date":"23日星期五"},{"fengxiang":"無持續風向","fengli":"微風級","high":"高溫 5℃","type":"多雲","low":"低溫 -3℃","date":"24日星期六"},{"fengxiang":"無持續風向","fengli":"微風級","high":"高溫 5℃","type":"陰","low":"低溫 -2℃","date":"25日星期天"},{"fengxiang":"無持續風向","fengli":"微風級","high":"高溫 4℃","type":"多雲","low":"低溫 -2℃","date":"26日星期一"}],"yesterday":{"fl":"3-4級","fx":"北風","high":"高溫 5℃","type":"晴","low":"低溫 -6℃","date":"21日星期三"},"aqi":"124","city":"北京"}}
download progress = 84
download progress = 86
download progress = 88
download progress = 91
download progress = 93
download progress = 95
download progress = 99
download progress = 100
HTTP/1.1 200 OK
resp={"error_code":2000,"msg":"OK","filepath":"uploadfiles/192.168.31.72_android_bug_1.png"}      

下載下傳過程有進度回調。

相關的libs包,可以在如下連結中下載下傳:​​javascript:void(0)​​

上述代碼,既可以在J2SE,J2EE中使用,也可以在Android中使用,在android中使用時,需要相關的權限。

另外,測試所使用的Web項目為:​​https://github.com/nuptboyzhb/SSHMySQLDemo​​