由于工作需要,学习了下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端的代码
Upload.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
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(); } } |
UploadListener.java
1 2 3 4 5 6 7 |
package cn.beyondcompare.uploader; public interface UploadListener { public void onUploadProcess(int size); public void onUploadFinished(String msg); |
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
package cn.beyondcompare.uploader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.ProtocolException; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private TextView txtVServerUrl = null; private TextView txtVFilePath = null; private Button btnUpload = null; private ProgressBar progressBar = null; private String filePath = "/mnt/sdcard/"; private String fileName = "android.pdf"; private String serverUrl = "http://10.0.2.2/upload.php"; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0) { progressBar.setProgress(msg.arg1); } else if (msg.what == 1) { Bundle b = msg.getData(); if (b == null) { return; } String str = b.getString("msg"); Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show(); } } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtVServerUrl = (TextView) findViewById(R.id.ID_TxtV_ServerUrl); txtVServerUrl.setText("serverUrl:" + serverUrl); txtVFilePath = (TextView) findViewById(R.id.ID_TxtV_FilePath); txtVFilePath.setText("filePath:" + filePath + fileName); progressBar = (ProgressBar) findViewById(R.id.ID_PBar); File file = new File(filePath, fileName); progressBar.setMax((int) file.length()); btnUpload = (Button) findViewById(R.id.ID_Btn_Upload); btnUpload.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final UploadTools uploadTools = new UploadTools(MainActivity.this, serverUrl, "heihei", "haha", filePath, fileName); uploadTools.setUploadListener(new UploadListener() { @Override public void onUploadProcess(int size) { Message msg = new Message(); msg.what = 0; msg.arg1 = size; handler.sendMessage(msg); } @Override public void onUploadFinished(String msg) { Message msg1 = new Message(); msg1.what = 1; Bundle b = new Bundle(); b.putString("msg", msg); msg1.setData(b); handler.sendMessage(msg1); } }); new Thread() { @Override public void run() { try { uploadTools.uploadFile(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } }); } |
php端代码比较简单:
upload.php
1 2 3 4 5 6 7 8 9 10 11 |
< ?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']; } |
参考:
http://blog.csdn.net/sxwyf248/article/details/7012496
http://blog.csdn.net/sxwyf248/article/details/7012758
http://tkxxd.net/thread-307-1-1.html
1 条评论
很有用谢谢!!