您的位置:首页 > 移动开发 > Android开发

android上传文件和参数到web服务器,php接收并保存

2013-01-19 10:21 751 查看
最近在做的Android应用需要用到文件上传功能,所以在网上查了好多资料。这篇说的比较清楚,所以转了。

原文链接:原文:android上传文件和参数到web服务器,php接收并保存

由于工作需要,学习了下android端上传文件到web服务器,服务器端使用php。

网上很多方法中并没有介绍参数如何和文件同时传送给服务器,本文给出了方法。

下面http请求中,实际生成的头部如下所示:
Host: example.com
Content-type: multipart/form-data, boundary=ahhjifeohiawf
Content-Length: $requestlen

–ahhjifeohiawf
content-disposition: form-data; name=”param1″

heihei
–ahhjifeohiawf
content-disposition: form-data; name=”param2″

haha
–ahhjifeohiawf
content-disposition: form-data; name=”uploadfile”; filename=”android.pdf”

(文件数据略)
–ahhjifeohiawf–

boundary是标示符,要保证它的值不出现在要传送的数据中,详细请看代码注释。

下面是详细android端和php端的代码

package cn.beyondcompare.uploader;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

import org.apache.http.HttpStatus;

import android.content.Context;
import android.util.Log;

public class UploadTools {
private static final String TAG = "[UploadTools]:";

private Context context = null;
private String serverUrl = null;
private String param1 = null;
private String param2 = null;
private String filePath = null;
private String fileName = null;

private static final int DEFAULT_BUFF_SIZE = 8192;
private static final int READ_TIMEOUT = 15000;
private static final int CONNECTION_TIMEOUT = 15000;

private UploadListener uploadListener = null;

public UploadTools(Context context, String url, String param1, String param2, String filePath, String fileName) {
this.context = context;
this.serverUrl = url;
this.param1 = param1;
this.param2 = param2;
this.filePath = filePath;
this.fileName = fileName;
}

public void setUploadListener(UploadListener listener) {
this.uploadListener = listener;
}

public void uploadFile() throws MalformedURLException, ProtocolException, FileNotFoundException, IOException {
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "ahhjifeohiawf";// 各个参数的间隔符,可自定义,但不能与发送内容有重复部分

if (context == null || serverUrl == null || param1 == null || param2 == null || filePath == null || fileName == null) {
return;
}

URL url = new URL(serverUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
// 设置每次传输的流大小,可以有效防止手机因为内存不足崩溃
// 此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。
httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K
// 允许输入输出流
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.setUseCaches(false);
// 超时时间设置
httpURLConnection.setReadTimeout(READ_TIMEOUT);
httpURLConnection.setConnectTimeout(CONNECTION_TIMEOUT);
// 使用POST方法
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Connection", "Keep-alive");
httpURLConnection.setRequestProperty("Charset", "UTF-8");
httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

DataOutputStream dos = new DataOutputStream(httpURLConnection.getOutputStream());
// 发送jsonStr
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"param1\"" + lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(param1);
dos.writeBytes(lineEnd);
// 发送acrion
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"param2\"" + lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(param2);
dos.writeBytes(lineEnd);
// 发送文件
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"" + fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
String srcPath = filePath + fileName;

FileInputStream fis = new FileInputStream(srcPath);
byte[] buffer = new byte[DEFAULT_BUFF_SIZE]; // 8k
int counter = 0;
int count = 0;
// 读取文件
while ((count = fis.read(buffer)) != -1) {
dos.write(buffer, 0, count);
counter += count;
if (uploadListener != null) {
uploadListener.onUploadProcess(counter);
}
}
fis.close();

dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);// 最后多出"--"作为结束
dos.flush();

if (httpURLConnection.getResponseCode() == HttpStatus.SC_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()), 8192);// 8k
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {

sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
if (uploadListener != null) {
uploadListener.onUploadFinished(sb.toString());
}

} else {
Log.d(TAG, "Http request failed!");
if (uploadListener != null) {
uploadListener.onUploadFinished("Http request failed!");
}
}

if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
}

另外两段Android代码我没转,因为这段上传的代码是最关键的。

PHP接收的代码

< ?php

echo "param1=".$_POST['param1'].chr(13).chr(10);
echo "param2=".$_POST['param2'].chr(13).chr(10);
$target_path  = "./upload/";//接收文件目录
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ".  basename( $_FILES['uploadedfile']['name']). " has been uploaded";
}  else{
echo "There was an error uploading the file, please try again!" . $_FILES['uploadedfile']['error'];
}
?>

参考:

Android上传文件到Web服务器,PHP接收文件(一)

Android上传文件到Web服务器,PHP接收文件(二)

通过 http 协议上传文件(rfc1867协议概述) multipart/form-data;boundary 解释
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: