利用js實現文件上傳

第一次寫博客,也不知怎麼去寫,這次也算是一個開頭吧。之前也一直關注別人寫的博客,他們寫的挺好,我從中也收穫不少。

首先,對於編程,我並非科班出身。我本科學的是統計學,其實更確切的說是學數學的,因爲我們大部分的課程是被數學佔滿了。可能有些人會奇怪,統計學幹嘛學那麼數學。因爲我學的是數理統計,學校很深厚的數學功底,也因爲這樣我纔會轉行做軟件的。這次我分享的是用js實現文件上傳的功能,首先說明一下,此技術並非都是我原創,我是阿發你好課程的基礎上改編的,他原創的沒有圖片預覽的功能,我在他的基礎上增加圖片預覽的功能。順便給發哥打一下廣告,他的課程真心不錯,我在他那裏學到很多原理上的東西,這是他的官方網址http://afanihao.cn/我只負責推薦,學不學看你自己。

好了廢話不多說了,直接上代碼吧,所有思路代碼都有註釋。

一、前端HTML部分

<div class='main'>
			<input type='file' class='filebutton' style='display:none' onchange='fileSelected()'  /> <br>
			<button class="upload" onclick='openFileDialog()' > 選擇文件上傳 </button>
			<div class="img">
			
			</div>
	   </div>

二、js部分

 //點擊普通按鈕,打開文件選擇框
	    function openFileDialog()
	    {
	    	$(".filebutton").click();
	    }
	    //選擇一個文件時onchange時間被觸發
	    function fileSelected()
	    {
	    	var fbutton = $(".filebutton")[0];//dom元素
	    	//讀取文件
	    	var reader = new FileReader();
	    	reader.onload = function(e)
	    	{
	    		var dataURL = e.target.result;//'data:image/jpeg;base64,/9j/4AAQSk...(base64編碼)...'   
	    		//alert(data);
	    		var htmlImg = "<img src = '" + dataURL + "'/>";
		    	$(".img").html(htmlImg);
	    	}
	    	var file = fbutton.files[0];
	    	reader.readAsDataURL(file);
	    	
	    	startFileUpload(file);	    	
	    }
	    //開始上傳
	    function startFileUpload(file)
	    {
	    	var uploadURL = "FileUploadServer";
	    	
	    	//手工構造一個form對象
	    	var formData = new FormData();
	    	formData.append("file" , file);// 'file' 爲HTTP Post裏的字段名, file 對瀏覽器裏的File對象
	    	//手工構造一個請求對象,用這個對象發送表單數據
	    	//設置 progress, load, error, abort 4個事件處理器
	    	var request = new XMLHttpRequest();
	    	request.upload.addEventListener("progress" , window.evt_upload_progress , false);
		    request.addEventListener("load", window.evt_upload_complete, false);
		    request.addEventListener("error", window.evt_upload_failed, false);
		    request.addEventListener("abort", window.evt_upload_cancel, false);			
			request.open("POST", uploadURL ); // 設置服務URL
		    request.send(formData);  // 發送表單數據
	    }
	    window.evt_upload_progress = function(evt)
	    {
	    	if(evt.lengthComputable)
	    	{
	    		
	    		var progress = Math.round(evt.loaded * 100 / evt.total);
	    		console.log("上傳進度" + progress);
	    	}
	    };
		window.evt_upload_complete = function (evt)
		{
			if(evt.loaded == 0)
			{
				console.log ("上傳失敗!");
			}
			else
			{
				console.log ("上傳完成!");
		    	var response = JSON.parse(evt.target.responseText);
		    	console.log (response);
			}			
		};		 
		window.evt_upload_failed = function (evt) 
		{			
			console.log  ("上傳出錯"); 
		};
		window.evt_upload_cancel = function (evt) 
		{
			console.log( "上傳中止!");	
		};

三、後端部分,需要兩個jar包的支持,他們分別是:commons-fileupload-1.3.1.jar   commons-io-2.4.jar

package my.fileUpload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.json.JSONObject;

public class FileUploadServer extends HttpServlet {

	File tmpDir;//文件保存的臨時目錄
	
	@Override
	public void init() throws ServletException {
		System.out.println("初始化");
	   File webRoot = new File(getServletContext().getRealPath("/"));
	   tmpDir = new File(webRoot , "upload");
	   if(!tmpDir.exists()) tmpDir.mkdirs();
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request , response);

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("進入");
		int error = 0;
		String reason = "OK";
		String data = null;
		try {
			 data = doUpload(request , response);
		} catch (Exception e) {
			error = -1;
			reason = e.getMessage();
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		JSONObject jreq = new JSONObject();
		jreq.put("error", error);
		jreq.put("reason", reason);
		if(data != null) jreq.put("data", data);
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/plain");
		PrintWriter out = response.getWriter();
		out.write(jreq.toString(2));

	}
	
	private String doUpload(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		String result = null;
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		if(!isMultipart)
			throw new Exception("請求編碼必須爲: multipart/form-data !");
		request.setCharacterEncoding("utf-8");
		ServletFileUpload upload = new ServletFileUpload();
		FileItemIterator iter = upload.getItemIterator(request);
		while(iter.hasNext())
		{
			//表單域
			FileItemStream item = iter.next();
			String fieldName = item.getFieldName();
			InputStream fieldStream = item.openStream();
			if(item.isFormField())
			{
				//普通表單域直接讀取
				String fieldValue = Streams.asString(fieldStream , "utf-8");
				System.out.println("表單域:" + fieldName + "=" + fieldValue);				
			}
			else
			{
				String realName = item.getName();//原始文件名
				//文件的後綴名
				String suffix = realName.substring(realName.lastIndexOf(".")+1);
				System.out.println("文件名:" + realName + "....." + "後綴名:" + suffix);
				
				//創建已個臨時文件名
				String s = UUID.randomUUID().toString();
				String s2 = s.substring(0,8)+s.substring(9,13)+s.substring(14,18)+s.substring(19,23)+s.substring(24); 
				s2 = s2.toUpperCase();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
				String dateStr = sdf.format(new Date());
				String fileName = dateStr +"-" + s2 + "." + suffix;
				result = fileName;
				System.out.println("文件名:" + fileName);
				File file = new File(tmpDir , fileName);
				long fileSsize = 0;//文件大小
				System.out.println("===========文件開始上傳=============");
				//從FieldStream讀取數據,保存到目標文件
				file.getParentFile().mkdirs();
				FileOutputStream fileStream = new FileOutputStream(file);
				try
				{
					byte[] buf = new byte[1024];
					while(true)
					{
						int n = fieldStream.read(buf);
						if(n < 0) break;
						if(n == 0) continue;
						fileStream.write(buf, 0, n);
						
						fileSsize += n;
					}
				}finally
				{
					fileStream.close();
					fieldStream.close();
				}
				System.out.println("上傳完成!");
				
				
			}
		}
		return result;
	}

}

最後再說一下,代碼會很多需要改進的地方,歡迎各位同僚給出意見,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章