Android檔案上傳-本地+伺服器一條龍分析

來源:互聯網
上載者:User

標籤:android   檔案上傳   servlet   伺服器   

本地:

先看下項目結構

MainActivity.java

package com.huxq.uploadexample;import java.io.File;import android.annotation.SuppressLint;import android.app.Activity;import android.app.ProgressDialog;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.Toast;public class MainActivity extends Activity implements OnUploadListener {// 伺服器路徑,換成自己的private String urlString = "http://192.168.1.2:8080/UploadTest/Upload";/** * 上傳檔案的路徑 */String filePath;/** * 上傳的檔案名稱 */String fileName;ProgressDialog dialog;/** * 在讀取檔案流的時候,同一進度會多次回調,通過這個標記,只有在進度更新的情況下才會更新ui 節省資源 */int oldProcess;@SuppressLint("HandlerLeak")private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {Log.i("process", "process" + msg.arg1);dialog.setProgress(msg.arg1);// 第一次沒有顯示dialog的時候顯示dialogif (!dialog.isShowing()) {Log.i("process", "show");dialog.show();} else {if (msg.arg1 == 100) {// 提示使用者上傳完成dialog.dismiss();toast("上傳完成!");}}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initProgressDialog();}public void upLoad(View v) {if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// toast("上傳");String sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();filePath = sdcardPath + "/Abook/";File file = new File(filePath);// 這裡我選的是Abook檔案夾下第五個檔案上傳,得根據自己的實際情況來,否則肯定出錯。fileName = file.list()[4];filePath += fileName;Log.i("file.size", "size=" + file.list().length + "filePath"+ filePath);} else {toast("沒有記憶卡");return;}new Thread() {public void run() {try {String response = HttpUtil.sendFile(urlString, filePath,fileName, MainActivity.this);Log.i("response", "response" + response);} catch (Exception e) {e.printStackTrace();}};}.start();}@Overridepublic void onUpload(double process) {process = process * 100;int currentProcess = (int) process;dialog.setProgress(currentProcess);// 避免重複發訊息,可以把if給去掉看看會發生什麼if (currentProcess > oldProcess) {Message msg = handler.obtainMessage();msg.arg1 = (int) process;handler.sendMessage(msg);}oldProcess = currentProcess;}public void initProgressDialog() {dialog = new ProgressDialog(this);dialog.setMax(100);dialog.setProgress(0);dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);dialog.setCancelable(false);dialog.setCanceledOnTouchOutside(false);dialog.setTitle("正在努力上傳...");}public void toast(String text) {Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();}}
HttpUtil.java

public static String sendFile(String urlPath, String filePath,String newName,OnUploadListener listener) throws Exception {String end = "\r\n";String twoHyphens = "--";String boundary = "******";URL url = new URL(urlPath);HttpURLConnection con = (HttpURLConnection) url.openConnection();//下載需要將setDoInput方法的參數值設為truecon.setDoInput(true);//上傳需要將setDoOutput方法的參數值設為truecon.setDoOutput(true);//禁止HttpURLConnection使用緩衝con.setUseCaches(false);//使用POST請求,必須大寫con.setRequestMethod("POST");//以下三行設定http要求標頭資訊con.setRequestProperty("Connection", "Keep-Alive");con.setRequestProperty("Charset", "UTF-8");//在類比web頁面向伺服器端上傳檔案時,每個檔案的開頭需要有一個分界符,//分界符需要在http要求標頭中指定。boundary是任意一個字串,一般為******con.setRequestProperty("Content-Type", "multipart/form-data;boundary="+ boundary);DataOutputStream ds = new DataOutputStream(con.getOutputStream());ds.writeBytes(twoHyphens + boundary + end);//上傳檔案相關資訊,這些資訊包括請求參數名,上傳檔案名稱,檔案類型,但並不限於此ds.writeBytes("Content-Disposition: form-data; "+ "name=\"file1\";filename=\"" + newName + "\"" + end);ds.writeBytes(end);//獲得檔案的輸入資料流,通過流傳輸檔案。在這裡我重寫了FileInputStream,為了監聽上傳進度CustomFileInputStream fStream = new CustomFileInputStream(filePath);fStream.setOnUploadListener(listener);/* 設定每次寫入1024bytes */int bufferSize = 1024;byte[] buffer = new byte[bufferSize];int length = -1;// 從檔案讀取資料至緩衝區 while ((length = fStream.read(buffer)) != -1) {//將資料寫入DataOutputStream中 ds.write(buffer, 0, length);}ds.writeBytes(end);ds.writeBytes(twoHyphens + boundary + twoHyphens + end);fStream.close();ds.flush();//上傳完成以後擷取伺服器的反饋InputStream is = con.getInputStream();int ch;StringBuffer b = new StringBuffer();while ((ch = is.read()) != -1) {b.append((char) ch);}ds.close();return b.toString();}
CustomFileInputStream.java

package com.huxq.uploadexample;import java.io.File;import java.io.FileDescriptor;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class CustomFileInputStream extends FileInputStream {private OnUploadListener listener;private int total, done;private double process;public CustomFileInputStream(File file) throws FileNotFoundException {super(file);available();}public CustomFileInputStream(FileDescriptor fd) {super(fd);available();}public CustomFileInputStream(String path) throws FileNotFoundException {super(path);available();}@Overridepublic int read(byte[] buffer, int byteOffset, int byteCount)throws IOException {done += byteCount;process = 1.0 * done / total;if (listener != null) {listener.onUpload(process);}return super.read(buffer, byteOffset, byteCount);}public void setOnUploadListener(OnUploadListener listener) {this.listener = listener;}@Overridepublic int available() {try {// 擷取檔案的總大小total = super.available();} catch (IOException e) {e.printStackTrace();}return total;}}
OnUploadListener.java

package com.huxq.uploadexample;public interface OnUploadListener {void onUpload(double process);}

伺服器端:

伺服器端通過一個servlet來接收檔案流,然後寫入磁碟就行了。

Upload.java

package com.huxq.test;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.Iterator;import java.util.List;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileItemFactory;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;/** * Servlet implementation class Upload */@WebServlet("/Upload")public class Upload extends HttpServlet {private static final long serialVersionUID = 1L;/** * 檔案儲存路徑 */private final String savaPath="E:\\uploads/";/** * Default constructor. */public Upload() {}/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse *      response) */protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean isMultipart = ServletFileUpload.isMultipartContent(request);if (isMultipart) {FileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);List items;try {items = upload.parseRequest(request);Iterator iter = items.iterator();// 可以接收多個檔案while (iter.hasNext()) {FileItem item = (FileItem) iter.next();if (item.isFormField()) {// 普通文本資訊處理String paramName = item.getFieldName();String paramValue = item.getString();System.out.println(paramName + ":" + paramValue);} else {// 上傳檔案資訊處理String fileName = item.getName();byte[] data = item.get();String filePath = savaPath + fileName;File file = new File(savaPath);if (!file.exists()) {file.mkdirs();}System.out.println("filePath:" + filePath);File file2 = new File(filePath);if (file2.exists())file2.delete();FileOutputStream fos = new FileOutputStream(file2);fos.write(data);fos.close();}}response.getWriter().write("UPLOAD_SUCCESS");} catch (FileUploadException e) {e.printStackTrace();response.getWriter().write("UPLOAD_FAILED");}}}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse *      response) */protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

這裡需要兩個jar包,分別是commons-fileupload-1.3.1.jar和commons-io-2.4.jar

所有想說的都在代碼裡了,如果有不清楚的可以下載下載Demo或者留言一起探討。


Android檔案上傳-本地+伺服器一條龍分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.