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

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本