Android中HttpClient网络请求

HttpClient是Apache对Java提供方法的一些封装, 在Android2.2版本之前,建议使用。
特点:上传文件很便利, 不过须要导入apache-mime4j-0.6.jar和httpmime-4.0.jar。注意默认不带gzip压缩。

public class HttpClientUtil {
 public static final int READ_TIMEOUT = 30*1000;
 public static final int CONNECT_TIMEOUT = 10*1000;
 public static final int EXCEPTION_ERR = 888;
 // 文件下载的状态
 public static final int DOWNLOAD_FAIL = -1;  //下载失败
 public static final int DOWNLOAD_PART = 0;  //下载了一部分
 public static final int DOWNLOAD_COMPLETE = 1;  //完全下载
 
 /**
  * 采用POST方式提交数据流
  * @param handler
  *             用消息发送机制返回HTTP Response结果
  * @param urlStr
  *             链接
  * @param params
  *             提交到服务器的参数
  * @param files
  *             提交到服务器的文件
  * */
 public static void postWithHttpClient(Handler handler, String urlStr,
   Map<String, String> params, Map<String, File> files){
  Message msg = handler.obtainMessage();
  HttpPost post = null;
  try{
   post = new HttpPost(urlStr);
   HttpParams http_param = new BasicHttpParams();
   HttpConnectionParams.setConnectionTimeout(http_param, CONNECT_TIMEOUT);//socket建立链接的超时时间。
   HttpConnectionParams.setSoTimeout(http_param, CONNECT_TIMEOUT);//建立链接成功后,获取response的返回等待时间。
   ConnManagerParams.setTimeout(http_param, CONNECT_TIMEOUT);//从连接池中取连接的超时时间 
   post.setParams(http_param);
   MultipartEntity entity = new MultipartEntity();
   if (params != null) { //添加参数
    for (Map.Entry<String, String> entry : params.entrySet()) {
     entity.addPart(entry.getKey(), new StringBody(entry.getValue(), Charset.forName("UTF-8")));
    }
   }
   if (files != null) { //添加文件
    for (Map.Entry<String, File> entry : files.entrySet()) {
     entity.addPart(entry.getKey(), new FileBody(entry.getValue(), entry.getValue().getName()));
    }
   }
   post.setEntity(entity);
  
   HttpClient client = new DefaultHttpClient();
   HttpResponse response = client.execute(post);
   int statuscode = response.getStatusLine().getStatusCode();
   msg.what = statuscode;
   HttpEntity e = response.getEntity();
   if ( e!=null ) {
    msg.obj = EntityUtils.toString(e);
   } else {
    msg.obj = "";
   }
  } catch (Exception e) {
   msg.what = EXCEPTION_ERR;
   msg.obj = e.getMessage();
  } finally {
   msg.sendToTarget();
   if( post != null ){
    post.abort();
   }
  }
 }
 
 /**
  * 采用GET方式获取数据流
  * @param handler
  *             用消息发送机制返回HTTP Response结果
  * @param urlStr
  *             链接
  * */
 public static void getWithHttpClient(String url, Handler handler) {
  Message msg = handler.obtainMessage();
  HttpGet httpGet = null;
  try {  
   httpGet= new HttpGet(url);
   HttpParams httpParams = new BasicHttpParams();
   HttpConnectionParams.setConnectionTimeout(httpParams, CONNECT_TIMEOUT);
   HttpConnectionParams.setSoTimeout(httpParams, CONNECT_TIMEOUT);
   httpGet.setParams(httpParams);
   HttpClient httpClient = new DefaultHttpClient();
   HttpResponse response = httpClient.execute(httpGet);
   int statusCode = response.getStatusLine().getStatusCode();
   msg.what = statusCode;
   HttpEntity entity = response.getEntity();
   if (entity!=null) {
    msg.obj = EntityUtils.toString(entity);
   } else {
    msg.obj = "";
   }
  } catch (Exception e) {
   msg.what = EXCEPTION_ERR;
   msg.obj = e.getMessage();
  } finally {
   msg.sendToTarget();
   if( httpGet!=null ){
    httpGet.abort();
   }
  }
 }
 
 /**
  * 一次性全部下载
  * 1. 使用GET方法下载
  * 2. 不要设置SoTimeout,如果要设置,最好时间长一些,因为大文件的下载本来就耗时
  * 3. 下载过程采用一边读输入流,一边写入文件的方法,节约内存
  * 4. 如果只下载了一部分就被中断,但是服务器不支持断点续传的话,必须重新下载
  */
 public static int downloadWithHttpClient(DownloadFileInfo fileInfo) {
  HttpGet httpGet = null;
  InputStream is = null;
  RandomAccessFile savedfile = null;
  try {
   httpGet = new HttpGet(fileInfo.mURL);
   HttpParams httpParams = new BasicHttpParams();
   HttpConnectionParams.setConnectionTimeout(httpParams, CONNECT_TIMEOUT);
   httpGet.setParams(httpParams);
   
   HttpClient httpClient = new DefaultHttpClient();
   HttpResponse response = httpClient.execute(httpGet);
   //保存文件的标示
   Header[] headers = response.getAllHeaders();
   int headerSize = headers.length;
   for( int i = 0; i < headerSize; ++i ) {
    if (headers[i].getName().equalsIgnoreCase("ETag")){
     String etag = headers[i].getValue();
     fileInfo.mEtag = etag;
     break;
    }
   }
   
   //新建需要写入的RandomAccessFile
   File dir = new File(fileInfo.mFilePath);
   if(!dir.exists()){
    dir.mkdirs();
   }
   File file = new File(fileInfo.mFilePath+File.separator+fileInfo.mFileName);
   if(!file.exists()){
    file.createNewFile();
   }
   savedfile = new RandomAccessFile(file,"rwd");
   
   int responseCode = response.getStatusLine().getStatusCode();
   if ( responseCode == 200 ) {//用来表示请求成功.
    long len = response.getEntity().getContentLength();
    if( len <= 0 ) {
     return DOWNLOAD_FAIL;
    }
    fileInfo.mCompleteFileLength = len;
    
    int readSize = 0;
    byte[] buffer = new byte[1024];//1k内存
    is = response.getEntity().getContent();
    while( ( readSize = is.read(buffer) ) != -1 ) {
     // 循环从输入流中读1k数据,写入文件
     savedfile.write(buffer, 0, readSize);
     fileInfo.mCurrentFileLength += readSize;
    }
   } else {
    return DOWNLOAD_FAIL;
   }
   int status = DOWNLOAD_FAIL;
   if( fileInfo.mCurrentFileLength > 0 ) {
    if( fileInfo.mCurrentFileLength == fileInfo.mCompleteFileLength ) {
     status = DOWNLOAD_COMPLETE;
    } else {
     status = DOWNLOAD_PART;
    }
   }
   return status;
  } catch (Exception e) {
   e.printStackTrace();
   int status = DOWNLOAD_FAIL;
   if( fileInfo.mCurrentFileLength > 0 ) {
    status = DOWNLOAD_PART;
   }
   return status;
  } finally {
   if( httpGet != null ) {
    httpGet.abort();
   }
   if( is != null ) {
    try {
     is.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
   if( savedfile != null ) {
    try {
     savedfile.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
 }
 
 /** 
  * 断点续传下载
  **/
 public static int downloadRangeWithHttpClient(DownloadFileInfo fileInfo) {
  HttpGet httpGet = null;
  InputStream is = null;
  RandomAccessFile savedfile = null;
  try {
   httpGet = new HttpGet(fileInfo.mURL);
   HttpParams httpParams = new BasicHttpParams();
   HttpConnectionParams.setConnectionTimeout(httpParams, CONNECT_TIMEOUT);
   httpGet.setParams(httpParams);
   
   long startPos = fileInfo.mCurrentFileLength;//开始位置
   httpGet.addHeader("Range", "bytes=" + startPos + "-"); //设置获取实体数据的范围
   
   //新建需要写入的RandomAccessFile
   File file = new File(fileInfo.mFilePath+File.separator+fileInfo.mFileName);
   savedfile = new RandomAccessFile(file,"rwd");
   savedfile.seek(startPos);
   
   HttpClient httpClient = new DefaultHttpClient();
   HttpResponse response = httpClient.execute(httpGet);
    
   int responseCode = response.getStatusLine().getStatusCode();
   if ( responseCode == 206 ) {//断点续传成功的反馈值是206,不是200
    long len = response.getEntity().getContentLength();
    if( len <= 0 ) {
     return DOWNLOAD_FAIL;
    }
    
    byte[] buffer = new byte[1024];
    int readSize = 0;
    is = response.getEntity().getContent();
    while( (readSize=is.read(buffer)) != -1 ) {
     savedfile.write(buffer, 0, readSize);
     fileInfo.mCurrentFileLength += readSize;
    }
   } else {
    return DOWNLOAD_FAIL;
   }
   int status = DOWNLOAD_FAIL;
   if( fileInfo.mCurrentFileLength > 0 ) {
    if( fileInfo.mCurrentFileLength == fileInfo.mCompleteFileLength ) {
     status = DOWNLOAD_COMPLETE;
    } else {
     status = DOWNLOAD_PART;
    }
   }
   return status;
  } catch (Exception e) {
   e.printStackTrace();
   int status = DOWNLOAD_FAIL;
   if( fileInfo.mCurrentFileLength > 0 ) {
    status = DOWNLOAD_PART;
   }
   return status;
  } finally {
   if (httpGet!=null){
    httpGet.abort();
   }
   if(is!=null){
    try {
     is.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
   if(savedfile!=null){
    try {
     savedfile.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
 }
 
 /**
  * 判断是否可以断点续传
  * 
  * @param DownloadFileInfo 保存下载信息:
  *    mURL:下载链接
  *    mFilePath:指定下载文件保存路径
  *    mFileName:下载文件的文件名
  *    mCompleteFileLength:待下载文件的Size
  *    mCurrentFileLength:已经下载的文件的Size,用于断点续传
  *    mEtag:服务器为某个文件生产的唯一标识值,每次文件有更新该值就会变化。
  * */
 public static boolean shouldRangeDownload(DownloadFileInfo fileInfo){
  File file = new File(fileInfo.mFilePath+File.separator+fileInfo.mFileName);
  if(!file.exists()){
   // 原来下载的文件已经被删除了,重新下载
   fileInfo.clearFileSizeRecord();
   return false;
  }
  HttpGet httpGet = null;
  try {
   httpGet = new HttpGet(fileInfo.mURL);
   HttpClient httpClient = new DefaultHttpClient();
   HttpResponse response = httpClient.execute(httpGet);
   
   Header[] headers = response.getAllHeaders();
   boolean acceptRangesIsBytes = false;
   boolean eTagChanged = true;
   int headerSize = headers.length;
   for( int i = 0; i < headerSize; ++i ) {
    if(headers[i].getName().equalsIgnoreCase("Accept-Ranges")){
     if(headers[i].getValue().equalsIgnoreCase("bytes")){
      acceptRangesIsBytes = true;
     }
    } else if (headers[i].getName().equalsIgnoreCase("ETag")){
     if(fileInfo.mEtag!=null && headers[i].getValue().equalsIgnoreCase(fileInfo.mEtag)){
      eTagChanged = false;
     }
    }
   }
   if( acceptRangesIsBytes == true && eTagChanged == false ) {
    return true;
   } else {
    // 1. 服务器不支持断点续传
    // 2. ETag改变了
    // 应该重新下载整个文件
    return false;
   }
  } catch (Exception e) {
   return false;
  } finally {
   if( httpGet!=null ){
    httpGet.abort();
   }
  }
 }
}

你可能感兴趣的:(Android中HttpClient网络请求)