当前位置: 代码迷 >> Android >> Android http文件上传-本土+服务器一条龙分析
  详细解决方案

Android http文件上传-本土+服务器一条龙分析

热度:242   发布时间:2016-04-28 02:21:38.0
Android http文件上传-本地+服务器一条龙分析

本地:

先看下项目结构

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的时候显示dialog			if (!dialog.isShowing()) {				Log.i("process", "show");				dialog.show();			} else {				if (msg.arg1 == 100) {// 提示用户上传完成					dialog.dismiss();					toast("上传完成!");				}			}		};	};	@Override	protected 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();	}	@Override	public 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方法的参数值设为true		con.setDoInput(true);		//上传需要将setDoOutput方法的参数值设为true		con.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();	}	@Override	public 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;	}	@Override	public 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或者留言一起探讨。


  相关解决方案