您的位置:首页 > 理论基础 > 计算机网络

Android 基于Http协议的文件上传

2014-11-15 22:33 316 查看
本文介绍的基于Http协议的文件上传方法,Http协议文件上传的功能是通过RFC1867规范描述的,Chrome,IE,Mozila和Opera等浏览器都支持此功能。

这里我先介绍一个工具名字叫Fiddler,它是一个Web Debugger工具,我们这里用它去分析Http 上传文件的原始内容 ,格式如下:

POST http://192.168.1.100/Handler1.ashx HTTP/1.1

Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468

User-Agent: Fiddler

Host: 192.168.1.100

Content-Length: 263827

---------------------------acebdf13572468

Content-Disposition: form-data; name="fieldNameHere"; filename="QQ截图20140818223203.png"

Content-Type: image/png



Android利用Http协议上传文件也必须要遵循这个规范。所以我们代码的核心就是如何用代码实现这个规范,从而实现文件的上传,上面说了一些废话。

下面进入主题 

首先 要说明的一点是 由于上传是需要访问网络的,

所以一定要在AndroidManifest.xml 文件中添加访问网络的权限,如下所示:

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >

上传文件的代码

package com.example.imageupload.network;

import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;
import java.io.File;

public class UpFile {

public static int post(String actionUrl, File file) throws IOException {
//产生随机分隔内容
String BOUNDARY = UUID.randomUUID().toString();
String PREFIX = "--";
String LINEND = "\r\n";
String MULTIPART_FROM_DATA = "multipart/form-data";
String CHARSET = "UTF-8";
URL url = new URL(actionUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置超时时间单位是毫秒
conn.setReadTimeout(5 * 1000);
//设置允许输入
conn.setDoInput(true);
//设置允许输出
conn.setDoOutput(true);
//不允许使用缓存
conn.setUseCaches(false);
//设置请求的方法为Post
conn.setRequestMethod("POST");
//设置维持长连接
conn.setRequestProperty("Connection", "keep-alive");
//设置字符集为UTF-8
conn.setRequestProperty("Charset", CHARSET);
//设置文件的类型
conn.setRequestProperty("Content-type", MULTIPART_FROM_DATA + "; boundary=" + BOUNDARY);
DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
//发送文件数据
if (file != null) {
StringBuilder sb = new StringBuilder();
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINEND);
sb.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"" + LINEND);
sb.append("Content-Type: image/png"  + LINEND);
sb.append(LINEND);
//写入输出流中
outStream.write(sb.toString().getBytes());
//将文件读入输入流中
InputStream is = new FileInputStream(file);
byte[] buffer = new byte[1024];
int len = -1;
//写入输出流中
while ((len = is.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
is.close();
//添加换行标识
outStream.write(LINEND.getBytes());
}

byte[] endData = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
outStream.write(endData);
//发送数据
outStream.flush();
//获取响应码 上传成功返回的是200
int res = conn.getResponseCode();
return res;

}

}

还有说明的一点是,网络的操作一定要在子线程里完成, 否则会产生异常 

代码如下:

class Task extends AsyncTask<String, Integer, Integer> {

@Override
protected Integer doInBackground(String... strings) {
Integer result = -1;
try {
result = UpFile.post("http://192.168.1.100/Handler1.ashx",
new File(strings[0]));
}
catch (IOException e) {
e.printStackTrace();
}
//			result = UploadFile.upLoadFile("http://192.168.1.100/Handler1.ashx",
//					new File(strings[0]));
return result;
}

@Override
protected void onPostExecute(Integer result) {
Toast.makeText(MainActivity.this, "" + result, Toast.LENGTH_LONG).show();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息