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

2024-05-12 07:32

本文主要是介绍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的


这篇关于Android 使用HttpClient和第三方MiME文件上传类库,实现文件上传的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/981988

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置