圖片文件的上傳及顯示

前端:

直接通過圖片的URL加載圖片

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/jquery.min.js"></script>
		<script type="text/javascript" src="js/afquery.js"></script>
		
		<style>
			.main{
				
			}
			
			.main input{
				margin: 20px;
			}
			.main .upload{
				background-color: cornflowerblue;
				color: #fff;
				border: 1px solid #ccc;
				border-radius: 1px;
				padding: 8px 18px;
			}
		</style>
	</head>
	<body>
		<div class="main">
			<input type="file" class="filebutton" style="display: none" /><br />
			<button class="upload" οnclick="selectFile()">選擇文件上傳</button>
			<div>
				<img class="imagebox" src="" style="width: 300px;" />
			</div>
		</div>
	</body>
	<script>
		//初始化
		var up = new AfUploader();
		up.setButton('.filebutton');  // 設置file input控件
		up.setUploadUrl('FileUploadService'); // 設置服務URL
		up.setLogEnabled( false );
		
		// 事件處理 'start' 'progress' 'complete' 'error' 'abort'
		up.processEvent = function(event)
		{
			if(event == 'progress')
			{
				Af.log("進度: " + this.progress);
			}
			else if(event == 'complete')
			{
				Af.log("完成上傳");
				Af.log(this.response);
				
				var jresp = JSON.parse (this.response); 
				var url  = jresp.data.url;
				$('.imagebox').attr('src', url);
			}
		};
		
		//是否允許上傳
		up.beforeUpload = function()
		{
			if(this.file.size > 10*1000000)
			{
				alert("文件太大!");
				return false;
			}
			return true;
		};
		
		function selectFile()
		{
			up.openFileDialog();
		}
	</script>
</html>

 

 

這裏用到了封裝好的自定義文件上傳工具類(afquery.js):

網址:邵發老師

/*
 * 上傳工具類 
 */
function AfUploader()
{
	this.fileButton = null; // 原生DOM
	this.file = null; // 要上傳的文件
	this.uploadUrl = null; 
	this.status = 0; // 0, 1, 100, -1(失敗), -2(canceled)
	this.progress = 0; // 0-100
	this.response = "{}"; // 上傳完畢後服務器的返回值, 一般應該是一個JSON字符串
	this.enableLog = true; // 是否顯示內部打印
	
	// 輸入參數可以是:Selector / jQuery對象 / 原生DOM
	this.setButton = function(fileButton)
	{
		// 如果輸入參數是 Selector
		if(fileButton.constructor == String) fileButton = $(fileButton);
		
		// 如果輸入參數是jQuery對象, 則轉成DOM
		if(fileButton.constructor == jQuery)
		{
			if(fileButton.length==0) throw ("你的jQuery選擇器寫錯了!請檢查選擇器!");
			fileButton = fileButton[0];
		}
		
		// 先看原來有沒有綁定, 如果已經綁定了一個uploader,則返回原有對象
		if(fileButton.uploader != null)  return fileButton.uploader;
		
		// 創建新的uploader
		this.fileButton = fileButton;
		
		// 把上下文存放到DOM元素裏
		this.fileButton.uploader = this;
		
		// 添加回調,確保只添加一次
//			this.fileButton.removeEventListener("change", this.onFileChanged);
//			this.fileButton.addEventListener("change", this.onFileChanged);
		this.fileButton.addEventListener("change", function(){
			var ctx = this.uploader;
			var fileButton = this;
			if(fileButton.files.length == 0) return;		
			
			var file = fileButton.files[0];
			ctx.log("select file: " + file.name);
			fileButton.value = ''; // 清空選擇
			ctx.setFile(file);
			ctx.startUpload( );
		});
		
		return this;
	};
	
	this.setUploadUrl = function(url)
	{
		this.uploadUrl = url;
		return this;
	};
	
	// 事件處理 : 'start' 'progress' 'complete' 'error' 'abort'
	this.processEvent = function( event )
	{		
	};
	
	// 是否接受上傳, true:可以上傳; false:不能上傳
	this.beforeUpload = function()
	{
		return true;
	};
	
	this.setLogEnabled  = function( enabled)
	{
		this.enableLog = enabled;
		return this;
	};
	
	// 設置文件 (並不立即啓動)
	this.setFile = function(file)
	{
		this.file = file;
		return this;
	};
		
	// 打開文件對話框,讓用戶選擇文件
	this.openFileDialog = function()
	{
		if(this.fileButton == null) throw ("尚未初始化file button! 請調用 setButton() 進行設置!");

		$(this.fileButton).click();	
	};

	// 外部可以直接送進來一個 File 對象
	this.startUpload = function( )
	{
		if(this.uploadUrl == null) throw ("尚未設置uploadUrl,無法上傳! 請調用 setUploadUrl()進行設置!");
		if(this.file == null) throw ("尚未設置file! 請調用openFileDialog()打開文件選擇對話框!或者調用setFile()傳一個File對象!");
		
		var file = this.file;
		// 上傳測試: 是否允許上傳
		if( ! this.beforeUpload())
		{
			this.log("不滿足上傳條件 ! " + file.name);
			return;
		}
		
		this.log("開始上傳: " + file.name);

	   	var formData = new FormData();
		formData.append('file', file); // 'file' 爲HTTP Post裏的字段名, file 對瀏覽器裏的File對象
				    
	    var formRequest = new XMLHttpRequest();
	    formRequest.ctx = this;
	    formRequest.upload.ctx = this;
	    
	    formRequest.upload.addEventListener("progress", this.evt_upload_progress, false);
	    formRequest.addEventListener("load", this.evt_upload_complete, false);
	    formRequest.addEventListener("error", this.evt_upload_failed, false);
	    formRequest.addEventListener("abort", this.evt_upload_cancel, false);		
	
		this.processEvent('start');
		formRequest.open("POST", this.uploadUrl );
	    formRequest.send(formData);
	    
	    this.formRequest = formRequest; /* 保存這個上傳者對象, 用於調用其abort()函數 */
	   	this.status = 1;		   		   	
	   	return this;
	};
	
	// 取消上傳
	this.cancelUpload = function()
	{		
		if(this.formRequest != null)
		{
			try{
				this.formRequest.abort(); 
    			this.formRequest = null;
    			this.status = -2;
			}catch(err)
			{
				Af.log("取消上傳時出錯 :" + err);
			}
    	}
	};
	
	this.log = function(msg)
	{
		if(!this.enableLog) return;
		try {   console.log(msg);     } catch (err) {}
	};
	
	//////////////////////////////
	
	this.evt_upload_progress = function (evt) 
	{
		var ctx = this.ctx;
	    if (evt.lengthComputable)
	    {
	    	ctx.progress = Math.round(evt.loaded * 100 / evt.total);		    	
	    	ctx.log ("上傳進度: " + ctx.progress);		
	    	ctx.processEvent('progress');
	    }	        
	};
	this.evt_upload_complete = function (evt)
	{
		var ctx = this.ctx;
		if(evt.loaded == 0)
		{
			ctx.status = -1;
			ctx.log ("上傳失敗!" + ctx.file.name);
			ctx.processEvent('error');
		}
		else
		{
			ctx.status = 100;
	    	ctx.response = evt.target.responseText;
	   		ctx.log (ctx.response); 
	   		ctx.processEvent('complete');
		}			
	};		 
	this.evt_upload_failed = function (evt) 
	{			
		var ctx = this.ctx;
		ctx.status = -1;
		ctx.log ("上傳出錯"); 
		ctx.processEvent('error');
	};
	this.evt_upload_cancel = function (evt) 
	{
		var ctx = this.ctx;
		ctx.status = -2;
		ctx.log( "上傳中止!");	
		ctx.processEvent('abort');
	};
}

後端:

package my;

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

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.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;

@WebServlet("/FileUploadService")
public class FileUploadService extends HttpServlet
{
	// 文件上傳的臨時目錄 
	File tmpDir ;
	
	@Override
	public void init() throws ServletException
	{
		File webroot = new File(getServletContext().getRealPath("/"));
		tmpDir = new File(webroot, "upload");
		tmpDir.mkdirs(); // 上傳進來的文件存放在 WebRoot/upload/ 下
	}

	protected void doPost(HttpServletRequest request, 
			HttpServletResponse response) throws ServletException, IOException
	{
		JSONObject jresp = new JSONObject();
		try
		{
			Object data = doUpload(request, response);
			jresp.put("error", 0);
			jresp.put("reason",  "OK");
			if(data != null)
				jresp.put("data", data);
			
		} catch (Exception e)
		{
			jresp.put("error", -1);
			jresp.put("reason", e.getMessage());
		}
		
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/plain");			
		PrintWriter out = response.getWriter();
		out.write(jresp.toString(2));
		out.close();
	}
	
	private Object doUpload(HttpServletRequest request, 
			HttpServletResponse response) throws Exception
	{
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		if(!isMultipart)
			throw new Exception("請求編碼必須爲: multipart/form-data !");
		
		request.setCharacterEncoding("utf-8");
		
		ServletFileUpload upload = new ServletFileUpload();
		AfFileUploadInfo info = new AfFileUploadInfo();
		
		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");
				printLog("表單域:" + fieldName + "=" + fieldValue);		
			}
			else
			{
				// 生成唯一的文件名
		    	info.realName = item.getName(); // 原始文件名
		    	info.suffix = fileSuffix(info.realName); // 後綴
		    	info.tmpFileName = createTmpFileName(info.suffix); // 服務器臨時文件名
		    	info.tmpFile = new File(tmpDir, info.tmpFileName);
		    	info.fileSize = 0; // 文件大小	
		    	
		    	printLog("文件上傳開始:" + info.realName + " >> " + info.tmpFile);
		    	
		        // 從FieldStream讀取數據, 保存到目標文件			        
		        info.tmpFile.getParentFile().mkdirs();		        
		        FileOutputStream fileStream = new FileOutputStream(info.tmpFile);
		        try{
		        	// 從請求裏讀取文件數據,保存到本地文件
		        	info.fileSize = copy(fieldStream, fileStream);
		        }finally{
		        	try{ fileStream.close();}catch(Exception e){}
		        	try{ fieldStream.close();}catch(Exception e){}
		        }
		        
		        printLog("文件上傳完成:" + info.realName + ", 大小: " + info.fileSize);
			}
		}
		// storePath: /upload/20180817-225649-948CC60AFD374333924DF2F3A049417D.jpg
		String storePath = "/upload/" + info.tmpFileName;
		// contextPath: /demo1601
		String url = getServletContext().getContextPath() + storePath;
		
		JSONObject result = new JSONObject();
		result.put("storePath", storePath);
		result.put("url", url);
		return result;
	}
	
	private long copy(InputStream in, OutputStream out) throws Exception
	{
		long count = 0;
		byte[] buf = new byte[8192];
		while (true)
		{
			int n = in.read(buf);
			if (n < 0)
				break;
			if (n == 0)
				continue;
			out.write(buf, 0, n);

			count += n;
		}
		return count;
	}
	//////////////////////////////////////////////////
	
	private void printLog(String message)
	{
		System.out.println(message);
	}
	
	// 生成一個唯一的ID
	private String createUUID ()
	{
		 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); 
	     return s2.toUpperCase();
	}
	
	// 得到一個保證不重複的臨時文件名
	private String createTmpFileName(String suffix)
	{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
		String datestr = sdf.format(new Date());
		String name = datestr + "-" + createUUID() + "." + suffix;
		return name;
	}
	
	// 得到文件的後綴名
	public String fileSuffix(String fileName)
	{
		int p = fileName.lastIndexOf('.');
		if(p >= 0)
		{
			return fileName.substring(p+1).toLowerCase();
		}
		return "";
	}

}
package my;

import java.io.File;

public class AfFileUploadInfo
{
	public String realName;   //原始文件名
	public String suffix;   //後綴
	public String tmpFileName;  //服務器臨時文件名
	public File tmpFile;
	public long fileSize;  //文件大小
}

 

發佈了228 篇原創文章 · 獲贊 20 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章