Android 使用HttpClient和第三方MiME文件上传类库,实现文件上传

                                         Android 使用HttpClient和第三方MiME文件上传类库,实现文件上传

MainActivity中定义的方法

[java]  view plain copy
  1. private void httpUpload() {  
  2.           
  3.         //定义HttpClient对象  
  4.         HttpClient client = new DefaultHttpClient();  
  5.         //获得HttpPost对象  
  6.         HttpPost post = new HttpPost("http://192.168.1.106:8001/2012/upload.php");  
  7.         post.addHeader("charset", HTTP.UTF_8);    
  8.         //实例化  
  9.         MultipartEntity me = new MultipartEntity();  
  10.           
  11.         try {  
  12.               
  13.             me.addPart("content",new StringBody("12cccafasdfasdf"));  
  14.             me.addPart("title",new StringBody("csdnliwei"));  
  15.             me.addPart("local",new StringBody("beijing"));  
  16.             //设置流文件  
  17.             me.addPart("file"new InputStreamBody(new FileInputStream("/mnt/sdcard/test.jpg"), "image/pjpeg""fengjie.jpg"));  
  18.               
  19.             post.setEntity(me);  
  20.             //获得响应消息  
  21.             HttpResponse resp = client.execute(post);  
  22.               
  23.             if(resp.getStatusLine().getStatusCode()==200){  
  24.                   
  25.                 Toast.makeText(this"文件上传文成!"1).show();  
  26.                   
  27.             }  
  28.               
  29.         } catch (Exception e) {  
  30.               
  31.             e.printStackTrace();  
  32.         }  
  33.           
  34.     }  

 

服务器端PHP程序:

 

[php]  view plain copy
  1. <?php  
  2. header("Content-type:text/html;charset=utf-8");  
  3.   
  4. print_r($_FILES['file']);  
  5.   
  6. $filename = $_FILES['file']['name'];  
  7.   
  8. if(!$_FILES['file']['error']){  
  9.       
  10.    if(move_uploaded_file($_FILES['file']['tmp_name'],"./upload/".$filename)){  
  11.          
  12.          echo "文件上传成功";  
  13.          
  14.        }else{  
  15.            echo "文件上传失败le";  
  16.            }  
  17.   
  18. }else{  
  19.       
  20.     echo "文件上传错误";  
  21.     }  
  22.   
  23.  ?>  


就这样就ok,实现文件上传 


使用 HttpClient 4 进行文件上传

1. 概述

本教程我们将描述如何使用 HttpClient 4进行一次多文件上传操作 .

我们将使用  http://echo.200please.com  作为测试服务器,因为它是面向公众的,并且接受大多数类型的内容.

如果你想要深入学习并了解你可以使用  HttpClient 做到的其它很棒的事情  – 那就去看看 首要的 HttpClient 教程吧   .

2. 使用  AddPart  方法

让我们开始研究研究  MultipartEntityBuilder  对象,来向一个Http实体添加成分,它在稍后将会被通过一个POST操作上传.

这是向一个 HttpEntity添加成分来表示表单的一般方法 .

示例 2.1. - 使用两个文本成分和一个文件上传一个表单

File file = new File(textFileName, ContentType.DEFAULT_BINARY);
HttpPost post = new HttpPost("http://echo.200please.com");
FileBody fileBody = new FileBody(file);
StringBody stringBody1 = new StringBody("Message 1", ContentType.MULTIPART_FORM_DATA);
StringBody stringBody2 = new StringBody("Message 2", ContentType.MULTIPART_FORM_DATA);
// 
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("upfile", fileBody);
builder.addPart("text1", stringBody1);
builder.addPart("text2", stringBody2);
HttpEntity entity = builder.build();
//
post.setEntity(entity);
HttpResponse response = client.execute(post);

请注意我们也通过制定将会被服务器使用到的ContentType值来实例化File对象.

同样还请注意  addPart  方法有两个参数,作用就像是表单的键值对 . 除非服务器端实际需要这些值并使用了这些参数名称,它们就是有干系的,否则它们就会被简单的忽略掉.

3. 使用  addBinaryBody  和  addTextBody  方法

创建一个multipart实体更直接的方式就是使用  addBinaryBody  和  AddTextBody   方法. 这些方法服务于上传文本,文件,字符数组和  InputStream  对象. 我们用了一个简单的例子来描述如何使用它们 .

示例 3.1. - 上传一个文本和一个文本文件部分

HttpPost post = new HttpPost("http://echo.200please.com");
File file = new File(textFileName);
String message = "This is a multipart post";
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upfile", file, ContentType.DEFAULT_BINARY, textFileName);
builder.addTextBody("text", message, ContentType.DEFAULT_BINARY);
// 
HttpEntity entity = builder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);

注意这里不需要  FileBody  和  StringBody  对象

同样重要的是,大多数服务器不会检查文本体的  ContentType  , 因此 addTextBody  方法可能会忽略掉  ContentType  值 .

  addBinaryBody 的  API 接受一个  ContentType  - 但是它也有可能从一个二进制体来创建实体,而对应名称的表单参数持有了这个文件. 如前面小节所述,如果ContentType值没有被指定,一些服务器将不会识别这个文件.

接下来,我们将一个zip文件作为一个  InputStream 添加进来,  而图片文件将会被作为File对象被添加进来:

示例 3.2. - 上传一个Zip文件,一个图片文件和一个文本 

HttpPost post = new HttpPost("http://echo.200please.com");
InputStream inputStream = new FileInputStream(zipFileName);
File file = new File(imageFileName);
String message = "This is a multipart post";
MultipartEntityBuilder builder = MultipartEntityBuilder.create();         
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody
  ("upfile", file, ContentType.DEFAULT_BINARY, imageFileName);
builder.addBinaryBody
  ("upstream", inputStream, ContentType.create("application/zip"), zipFileName);
builder.addTextBody("text", message, ContentType.TEXT_PLAIN);
// 
HttpEntity entity = builder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);

请注意ContentType值可以被动态创建,正如上面这个针对zip文件的示例中所示 .

最后,不是所有的服务器都接受  InputStream  部分. 我们在代码的第一行实体化的服务器可以接受 .

让我们现在来看看另外一个示例,  addBinaryBody直接用于一个位数组  :

示例 3.3. - 上传一个位数组和文本

HttpPost post = new HttpPost("http://echo.200please.com");
String message = "This is a multipart post";
byte[] bytes = "binary code".getBytes(); 
// 
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upfile", bytes, ContentType.DEFAULT_BINARY, textFileName);
builder.addTextBody("text", message, ContentType.TEXT_PLAIN);
// 
HttpEntity entity = builder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);

留意 ContentType  - 它现在被指定为二进制数据.

4. 总结

本文呈现了  MultipartEntityBuilder 作为一个灵活的对象提供了创建一个  multipart 表单多种API.

示例同样也展示了如何使用HttpClient上传一个类似于表单实体的HttpEntity .

这些示例的所有实现和代码块在  我的github项目  中可以找到 – 这是一个基于Eclipse的项目, 因此可以很容易的导入并运行.





Httpmime-4.1.3 简单使用

HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议(CV大法来自于HttpClient百度百科,-  -),httpclient的jar包可去apache官网或者csdn或者iask下载(个人感觉iask还是不错的,至少好多资源免积分,而且里面还有很多意想不到的资源哦, -  -)。

言归正传,介绍项目中使用的httpmime-4.1.3.jar包使用,理解jar包里面的类定义及属性方法可参照其javadoc,下面直接上代码。

[java]  view plain copy
  1. public class HttpworkTask extends Thread {  
  2.     public final static String TAG = "HttpworkTask"//log tag  
  3.     private NetworkListener listener;  
  4.     private static HttpClient httpClient;  
  5.     private final static int CONNECTIONTIMEOUT = 10000;//http链接超时  
  6.     private final static int REQUESTTIMEOUT = 20000;//http数据请求超时  
  7.       
  8.       
  9.     private String url = null;  
  10.     private Map<String, Object> paras = null;//post的StringBody  
  11.     private Map<String, File> fileParas = null;//post的FileBody  
  12.   
  13.     public HttpworkTask(String url, Map<String, Object> paras, Map<String, File> fileParas){  
  14.         this.url = url;  
  15.         this.paras = paras;  
  16.         this.fileParas = fileParas;  
  17.     }  
  18.       
  19.     @Override  
  20.     public void run() {  
  21.           
  22.         BufferedReader br = null;  
  23.         StringBuilder sBuilder = new StringBuilder();  
  24.         HttpParams httpParams = new BasicHttpParams();  
  25.         HttpConnectionParams.setConnectionTimeout(httpParams, CONNECTIONTIMEOUT);  
  26.         HttpConnectionParams.setSoTimeout(httpParams, REQUESTTIMEOUT);  
  27.           
  28.         SchemeRegistry registry = new SchemeRegistry();    
  29.         registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));    
  30.         registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));  
[java]  view plain copy
  1.         //由于是使用线程操作http,所以设置Thread safe属性,不然当start多个httpworktask线程时必然报错,这点需要注意    
  2.         httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams);      HttpPost post = new HttpPost(url);  
  3.         //添加 post的String 和File数据  
  4.         MultipartEntity entity = new MultipartEntity();  
  5.         try {  
  6.             // 添加参数  
  7.             if (paras != null && !paras.isEmpty()) {  
  8.                 for (Map.Entry<String, Object> item : paras.entrySet()) {  
  9.                     entity.addPart(item.getKey(), new StringBody(item.getValue().toString(), Charset.forName("UTF-8")));  
  10.                 }  
  11.             }  
  12.   
  13.             // 添加文件  
  14.             if (fileParas != null && !fileParas.isEmpty()) {  
  15.                 for (Map.Entry<String, File> item : fileParas.entrySet()) {  
  16.                     if (item.getValue().exists()) {  
  17.                         Log.i(TAG, "upload File is exists and filepath is-->" + item.getKey() + "  " + item.getValue().getPath());  
  18.                         entity.addPart(item.getKey(), new FileBody(item.getValue()));  
  19.                     }else{  
  20.                         Log.e(TAG, "upload File is NOT exists!");  
  21.                     }  
  22.                       
  23.                 }  
  24.             }  
  25.             post.setEntity(entity);  
  26.   
  27.             HttpResponse response = httpClient.execute(post);  
  28.   
  29.             int statecode = response.getStatusLine().getStatusCode();  
  30.   
  31.             Log.i(TAG, "http response code-->" + statecode);  
  32.   
  33.             if (statecode == HttpStatus.SC_OK) {  
  34.                 HttpEntity responseEntity = response.getEntity();  
  35.                 if (responseEntity != null) {  
  36.                     InputStream is = responseEntity.getContent();  
  37.                     br = new BufferedReader(new InputStreamReader(is));  
  38.                     String tempStr;  
  39.                     while ((tempStr = br.readLine()) != null) {  
  40.                         sBuilder.append(tempStr);  
  41.                     }  
  42.                     br.close();  
  43.                 }  
  44.             }  
  45.         } catch (Exception e) {  
  46.                         listener.onConnectionError(NetworkListener.NET_ERROR, "http connect is error,pls check your phone network");  
  47.         } finally {  
  48.             if (br != null) {  
  49.                 try {  
  50.                     br.close();  
  51.                 } catch (IOException e) {  
  52.                     e.printStackTrace();  
  53.                 }  
  54.             }  
  55.         }  
  56.         post.abort();  
  57.         //http返回的数据  
  58.         String resData = sBuilder.toString();  
  59.         Log.i(TAG, "http server response -->" + resData);  
  60.         if (resData != null) {  
  61.             listener.onConnectionRecieveData(resData.getBytes(), resData.length());  
  62.         }  
  63.           
  64.           
  65.     }  
  66.   
  67.   
  68.     public static void shutdownHttp() {  
  69.         if (httpClient != null) {  
  70.             httpClient.getConnectionManager().shutdown();  
  71.         }  
  72.     }  
  73. }  
[java]  view plain copy
  1. 说明几点:1.使用MultipartEntity,Stringbody和FileBody可同时post。  
[java]  view plain copy
  1. 2.可同时上传n个File文件。  
[java]  view plain copy
  1. 一般在定义http业务的json协议时,如json上传照片文件,imgUrls:图片文件(同时上传多张图片),entity.addPart的第一个参数为fileParas map的key值应为imgUrls,这样多次addpart后会不会顶掉前面add的


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值