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 ...
随机推荐
- Hasor:生命周期
首先引用Wiki的介绍一下Hasor: “Hasor是一款开源框架.它是为了解决企业模块化开发中复杂性而创建的.Hasor遵循简单的依赖.单一职责,在开发多模块企业项目中更加有调理.然而Has ...
- hdu 4740【模拟+深搜】.cpp
题意: 给出老虎的起始点.方向和驴的起始点.方向.. 规定老虎和驴都不会走自己走过的方格,并且当没路走的时候,驴会右转,老虎会左转.. 当转了一次还没路走就会停下来.. 问他们有没有可能在某一格相遇. ...
- 从后台绑定数据到ligerui 的comboBox下拉框组件
这次来记录一下ligerUI的comboBox下拉框组件,ligerUI的API里也有相关描写叙述,上面都是前台写死数据,然后显示在组件中,我这次要说的是将后台的数据绑定到下拉框组件中,废话不多说. ...
- maven项目建立pom.xml报无法解析org.apache.maven.plugins:maven-resources-plugin:2.4.3
一.发现问题 建立maven项目后,pom.xml在显示红叉.鼠标放上去,显示Executiondefault-testResources of goalorg.apache.maven.plugin ...
- H264 编解码框架简单介绍
阅读完H264/AVC 编解码器的介绍,脑海中仅仅是留下下面三条: 1.H264并没有明白规定一个编解码器怎样实现,仅仅是规定了一个编码后的视频比特流的句法,和该比特流的解码方法,这个与MPEG 类似 ...
- 2014牡丹江——Hierarchical Notation
problemId=5380" style="background-color:rgb(51,255,51)">题目链接 字符串模拟 const int MAXN ...
- 第一章 andrid visdio 安装
第一章 andrid visdio 安装与环境搭建 一.Android Studio简介 Android Studio是Google新发布的Android应用程序开发环境,Android Stud ...
- 《JavaScript设计模式与开发实践》读书笔记之享元模式
1. 享元模式 享元模式是一种用于性能优化的模式,享元模式的核心是运用共享技术来有效支持大量细粒度的对象 1.1 传统的文件上传方法 以文件上传为例,文件上传功能可以选择依照队列,一个一个的排队上传, ...
- windows phone 7 定位(获取经纬度),然后找到经纬度所在的位置(城市信息)
原文:windows phone 7 定位(获取经纬度),然后找到经纬度所在的位置(城市信息) 前几天做项目用到, 代码贴给大家. /// <summary> /// 获取当前位置的经纬度 ...
- javascript UniqueID属性
在Web页中的每一个HTML元素都一个ID属性,ID作为其标示,在我们的普通理解中它应该是unique的.但是HTML元素的ID属性是可写的,这就造成了我们非常可能人为的使ID的反复.按么假设 ...