Android利用网络编程HttpClient批量上传(一个)
请尊重他人的劳动成果。转载请注明出处:Android网络编程之使用HttpClient批量上传文件
我曾在《Android网络编程之使用HTTP訪问网络资源》一文中介绍过HttpCient的使用,这里就不在累述了,感兴趣的朋友能够去看一下。在这里主要介绍怎样通过HttpClient实现文件上传。
1.预备知识:
在HttpCient4.3之前上传文件主要使用MultipartEntity这个类,但如今这个类已经不在推荐使用了。
随之替代它的类是MultipartEntityBuilder。
以下让我们了解一下MultipartEntityBuilder类:
MultipartEntityBuilder这个类主要用于创建HttpEntity。
它的主要方法有:
| 
 修饰符和类型  | 
 方法和描写叙述  | 
| 
 MultipartEntityBuilder  | 
 addBinaryBody(String name, 将字节数组以二进制的形式加入数据。  | 
| 
 MultipartEntityBuilder  | 
 addBinaryBody(String name, 将字节数组以二进制的形式加入数据。  | 
| 
 MultipartEntityBuilder  | 
 addBinaryBody(String name, File file) 将文件以二进制的形式加入数据。  | 
| 
 MultipartEntityBuilder  | 
 addBinaryBody(String name, File file, ContentType contentType, String filename) 将文件以二进制的形式加入数据。  | 
| 
 MultipartEntityBuilder  | 
 addBinaryBody(String name, InputStream stream)  | 
| 
 MultipartEntityBuilder  | 
 addBinaryBody(String name, InputStream stream, ContentType contentType, String filename) 将输入流以二进制的形式加入数据。  | 
| 
 MultipartEntityBuilder  | 
 addPart(String name, ContentBody contentBody) 加入ContentBody 类型的数据。  | 
| 
 MultipartEntityBuilder  | 
 addTextBody(String name, String text) 加入文本数据。  | 
| 
 MultipartEntityBuilder  | 
 addTextBody(String name, String text, ContentType contentType) 以指定的内容类型加入文本数据。  | 
| 
 HttpEntity  | 
 build() 创建一个HttpEntity。  | 
| 
 static MultipartEntityBuilder  | 
 create() 创建一个MultipartEntityBuilder对象。  | 
| 
 MultipartEntityBuilder  | 
 setBoundary(String boundary) 设置边界。  | 
| 
 MultipartEntityBuilder  | 
 setCharset(Charset charset) 设置请求的编码格式。  | 
| 
 MultipartEntityBuilder  | 
 setLaxMode()  | 
| 
 MultipartEntityBuilder  | 
 setMode(HttpMultipartMode mode) 设置模式。  | 
| 
 MultipartEntityBuilder  | 
 setStrictMode()  | 
主要方法说明:
addBinaryBody、addPart、addTextBody方法用于加入要上传的数据,从上面的表格中能够发现用于加入数据的方法,都是key-value类型。所以在server端我们能够通过request.getPart("keyname")方式获取相应key的数据。也能够通过request.getParts()方式获取client通过以上三种方法提交全部数据。
1.通过addBinaryBody方法直接能够加入File、InputStream、byte[]类型的数据。
2.通过addPart方法仅仅能加入ContentBody类型的数据,在org.apache.http.entity.mime.content包中已经提供了String、File以及InputStream相应的ContentBody类型的子类。如FileBody、InputStreamBody、StringBody,通过这些类我们能够将String、File以及InputStream类型的数据转换成ContentBody类型的数据。
3.通过addTextBody方法我们能够非常方便的加入文本数据。
2.通过HttpCient上传文件
Android端须要加入httpcore-4.3.2.jar、httpmime-4.3.5.jar两个包。两个包缺一不可。
在这里我用的是最新版的HttpCient。大家能够从http://hc.apache.org/downloads.cgi上下载所须要的jar包,假设上面的站点打不开。大家也不用操心,我已经将项目中所须要的jar包上传到CSDN上《httpcomponents-client-4.3.5-bin.zip》须要的朋友能够去下载。
Android端项目核心代码:
HttpClient client=new DefaultHttpClient();// 开启一个客户端 HTTP 请求
HttpPost post = new HttpPost(url);//创建 HTTP POST 请求
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
// builder.setCharset(Charset.forName("uft-8"));//设置请求的编码格式
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//设置浏览器兼容模式
int count=0;
for (File file:files) {
// FileBody fileBody = new FileBody(file);//把文件转换成流对象FileBody
// builder.addPart("file"+count, fileBody);
builder.addBinaryBody("file"+count, file);
count++;
}
builder.addTextBody("method", params.get("method"));//设置请求參数
builder.addTextBody("fileTypes", params.get("fileTypes"));//设置请求參数
HttpEntity entity = builder.build();// 生成 HTTP POST 实体
post.setEntity(entity);//设置请求參数
HttpResponse response = client.execute(post);// 发起请求 并返回请求的响应
if (response.getStatusLine().getStatusCode()==200) {
return true;
}
return false;
代码分析:
上面代码主要实现了多文件上传。为了方便server端保存文件,上面代码设置了名称为fileTypes的參数,fileTypes是由上传的文件类型名拼接成的字符串,如”.jpg.png.docx“;
server端能够通过获取名为fileTypes的參数。然后将其拆分成字符数组,就可以得到要保存文件的类型。
server端项目核心代码:
server段主要用到Servlet3.0的API,主要用到的方法有:
1. request.getParameter("");//获取client通过addTextBody方法加入的String类型的数据。
2. request.getPart("");//获取client通过addBinaryBody、addPart、addTextBody方法加入的指定数据,返回Part类型的对象。
3. request.getParts();//获取client通过addBinaryBody、addPart、addTextBody方法加入的全部数据,返回Collection<Part>类型的对象。
4. part.getName();//获取上传文件的名称即上传时指定的key。
5. part.getSize()//获取上传文件的大小单位为字节。
String fileTypes=request.getParameter("fileTypes");//获取client上传的全部文件类型
String[]typeArray=fileTypes.substring(1).split("\\.");//将文件类型字符串拆分成String数组
try {
	Iterator<Part>iterator=request.getParts().iterator();
	int count=0;
	while (iterator.hasNext()) {//遍历client上传的全部文件
		if (count>=typeArray.length)break;//假设超出文件类型数组的大小则跳出循环
		Part part = (Part) iterator.next();
//				System.out.println("part.getSize()"+part.getSize());//获取上传文件的大小
//				System.out.println("part.getName()"+part.getName());//获取上传文件的名及加入数据时的key名
		File file=new File("E:\\upload\\"+count+"."+typeArray[count++]);
		InputStream inputStream=part.getInputStream();
		FileOutputStream fos=new FileOutputStream(file);
		byte[]buffer=new byte[1024];
		int len=0;
		while ((len=inputStream.read(buffer))!=-1) {
			fos.write(buffer,0, len);
		}
		inputStream.close();
		fos.close();
	}
}catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}
代码分析:
server端是通过Servlet实现的,通过调用request.getParameter("fileTypes")方法来获取client上传的全部文件类型,然后将文件类型字符串拆分成String数组。通过request.getParts()方法取出client通过addBinaryBody、addPart、addTextBody上传的全部数据,然后遍历数据集合就可以进行文件的保存。
由于事先和client协定。加入上传文件的顺序在加入请求參数之前,所以能够依据拆分出的文件类型数组的长度推断出client上传文件的个数,因此当上面代码遍历超出了类型数组的长度时程序跳出循环。不再进行文件的保存,由于以下的Part都是些參数,而不是要保存的文件了。
程序执行效果图:

3.完毕项目代码:
package com.jph.ufh.activity; import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.jph.ufh.R;
import com.jph.ufh.service.UploadService;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Toast; /**
* 通过httpClient批量上传文件
* @author jph
* Date:2014.10.09
*/
public class MainActivity extends Activity {
private ArrayList<File>files;
private Map<String, String>params;
Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case UploadService.UPLOAD_SUCCESS:
Toast.makeText(MainActivity.this, "上传成功", Toast.LENGTH_LONG).show();
break;
}
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
files=new ArrayList<File>();
params=new HashMap<String, String>(); }
public void upload(View v) {
files.clear();
params.clear();
File file=new File(Environment.getExternalStorageDirectory(),"kaola.jpg");
File file2=new File(Environment.getExternalStorageDirectory(),"test.docx");
File file3=new File(Environment.getExternalStorageDirectory(),"test.jpg");
files.add(file);
files.add(file2);
files.add(file3);
StringBuffer sbFileTypes=new StringBuffer();
for (File tempFile:files) {
String fileName=tempFile.getName();
sbFileTypes.append(getFileType(fileName));
}
params.put("fileTypes",sbFileTypes.toString());
params.put("method", "upload");
UploadService uploadService=new UploadService(mHandler);
uploadService.uploadFileToServer(params, files);
}
/**
* 获取文件的类型
* @param fileName :文件名称
* @return 文件类型
*/
private String getFileType(String fileName) {
// TODO Auto-generated method stub
return fileName.substring(fileName.lastIndexOf("."), fileName.length());
}
}
package com.jph.ufh.service; import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.DefaultHttpClient; import android.os.Handler; /**
* 採用HttpClient上传文件,支持多文件上传
* @author jph
* Date:2014.10.09
*/
public class UploadService {
private static String url="http://10.219.57.16:8080/ServerForUpload/ServletForUpload";
// private static String url="http://10.110.6.58:8080/ServerForUpload/ServletForUpload";
public static final int UPLOAD_SUCCESS=0x123;
public static final int UPLOAD_FAIL=0x124;
private Handler handler;
public UploadService(Handler handler) {
// TODO Auto-generated constructor stub
this.handler=handler;
}
/**
* @param params 请求參数。包含请求的的方法參数method如:“upload”,
* 请求上传的文件类型fileTypes如:“.jpg.png.docx”
* @param files 要上传的文件集合
*/
public void uploadFileToServer(final Map<String, String> params, final ArrayList<File>files) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
if (uploadFiles(url,params,files)) {
handler.sendEmptyMessage(UPLOAD_SUCCESS);//通知主线程数据发送成功
}else {
//将数据发送给server失败
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
/**
* @param url servlet的地址
* @param params 要传递的參数
* @param files 要上传的文件
* @return true if upload success else false
* @throws ClientProtocolException
* @throws IOException
*/
private boolean uploadFiles(String url,Map<String, String>params,ArrayList<File>files) throws ClientProtocolException, IOException {
HttpClient client=new DefaultHttpClient();// 开启一个客户端 HTTP 请求
HttpPost post = new HttpPost(url);//创建 HTTP POST 请求
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
// builder.setCharset(Charset.forName("uft-8"));//设置请求的编码格式
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//设置浏览器兼容模式
int count=0;
for (File file:files) {
// FileBody fileBody = new FileBody(file);//把文件转换成流对象FileBody
// builder.addPart("file"+count, fileBody);
builder.addBinaryBody("file"+count, file);
count++;
}
builder.addTextBody("method", params.get("method"));//设置请求參数
builder.addTextBody("fileTypes", params.get("fileTypes"));//设置请求參数
HttpEntity entity = builder.build();// 生成 HTTP POST 实体
post.setEntity(entity);//设置请求參数
HttpResponse response = client.execute(post);// 发起请求 并返回请求的响应
if (response.getStatusLine().getStatusCode()==200) {
return true;
}
return false;
}
}
版权声明:本文博客原创文章。博客,未经同意,不得转载。
Android利用网络编程HttpClient批量上传(一个)的更多相关文章
- Android利用网络编程HttpClient批量上传(两)AsyncTask+HttpClient监测进展情况,并上传
		
请尊重别人的劳动.转载请注明出处: Android网络编程之使用HttpClient批量上传文件(二)AsyncTask+HttpClient并实现上传进度监听 执行效果图: 我曾在<Andro ...
 - 转 Android网络编程之使用HttpClient批量上传文件  MultipartEntityBuilder
		
请尊重他人的劳动成果,转载请注明出处:Android网络编程之使用HttpClient批量上传文件 http://www.tuicool.com/articles/Y7reYb 我曾在<Andr ...
 - Android okHttp网络请求之文件上传下载
		
前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...
 - 利用WebUploader进行图片批量上传,在页面显示后选择多张图片压缩至指定路径【java】
		
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览 ...
 - java网络编程之图片上传
		
输入输出流核心代码 所有的文件传输都是靠流,其中文件复制最具代表性.输入流和输出流,从输入流中读取数据写入到输出流中. InputStream in = 输入源; OutputStream os = ...
 - Java网络编程——TCP图片上传
		
1.编写一个服务器端程序,用来接收图片.创建一个监听指定端口号的ServerSocket服务端对象,在while(true)无限循环中持续调用ServerSocket的accept()方法来接收客户端 ...
 - 利用socket编程在ESP32上搭建一个TCP客户端
		
通过之前http://www.cnblogs.com/noticeable/p/7636582.html中对socket的编程,已经可以知道如何通过socket编程搭建服务器和客户端了,现在,就在ES ...
 - HttpClient MultipartEntityBuilder 上传文件
		
文章转载自: http://blog.csdn.net/yan8024/article/details/46531901 http://www.51testing.com/html/56/n-3707 ...
 - 使用WebUploader实现文件批量上传,进度条显示功能
		
知识点:利用WebUploader,实现文件批量上传,并且实时显示文件的上传进度 参考官方文档:http://fex.baidu.com/webuploader/ (1)引入三个资源 JS,CSS,S ...
 
随机推荐
- DOS批处理延时技术
			
DOS批处理延时技术 举个例子,我们要延时5秒打开gdh.txt这个文件,可以用以下几个方法 方法一:ping 缺点:时间精度为1秒,不够精确 www.2cto.com @echo off ...
 - SVN Error: “' 'x' isn't in the same repository as 'y' ” during merge (并不在同一个版本库中)
			
在使用svn merge命令报错 英文版本:SVN Error: “' 'x' isn't in the same repository as 'y' ” during merge 中文版本报错:并不 ...
 - LaTeX中表格多行显示的最简单设置方法
			
这事实上是一个非常easy的问题,可是这两天发现我之前的解决方式太麻烦了.简介一下这样的最简单的方法: 之前设置多行显示的时候,用类似于以下这样的方法进行多行显示: \begin{table} \ne ...
 - js:进一步关闭(范围:下一个)
			
function fn1(){ //创建一个数组 var fns = new Array(); //i这个变量是保存在fn1这个作用域中 for(var i=0;i<10;i++ ...
 - mysql 编译安装提示“checking for termcap functions library... configure: error: No curses/termcap library found”
			
原因: 缺少ncurses安装包 解决办法: 下载安装相应软件包 一.如果你的系统是RedHat系列: yum list|grep ncurses yum -y install ncurses-dev ...
 - mysql表修改
			
CREATE TABLE tab2 AS (SELECT * FROM tab1)这种做法表的存储引擎也会采用服务器默认的存储引擎而不是源表的存储引擎,此种复制方法把表的内容也一起复制过来了. CRE ...
 - 模拟Post
			
string d = "http://search.anccnet.com/searchResult2.aspx"; //name="__VIEWSTATE" ...
 - mysql copy复制拷贝表数据及结构的几种方式(转)
			
mysql拷贝表操作我们会常常用到,下面就为您详细介绍几种mysql拷贝表的方式,希望对您学习mysql拷贝表方面能够有所帮助.假如我们有以下这样一个表:id username password--- ...
 - Android他们控制的定义(一)
			
培养自己的控制步骤定义: 1.要理解View作品 2. 分享到继承View子类 3. 要定义自己的View类添加属性 4. 绘制控件 5. 响应用户消息 6 .自己定义回调函数 一.View ...
 - Oracle SQL Lesson (11) - 创建其他数据库对象(试图/序列/索引/同义词)
			
schema(模式)一个用户下一组对象的集合,一般与用户名一致. 视图 CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view [(alias[, alias].. ...