文件上傳(form實現)

 文件上傳:即通過網頁方式,打開文件對話框,選擇文件並上傳到服務器

如:

發送email時選擇附件,修改用戶頭像等

當點擊上傳後,文件存儲到對應的目錄

上傳成功後,後端返回數據

前端

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		
		<style>
			.main{
				
			}
			
			.main input{
				margin: 20px;
			}
			.main input[type='submit']{
				background-color: cornflowerblue;
				color: #fff;
				border: 1px solid #ccc;
				border-radius: 1px;
				padding: 8px 18px;
			}
		</style>
	</head>
	<body>
		<div class="main">
			<form method="post" action="FileUploadService" enctype="multipart/form-data">
				<input type="file" name="fileUpload"/><br />
				<input type="submit" value="上傳"/><br />
			</form>
		</div>
	</body>
</html>

後端

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;

/**
 * Servlet implementation class FileUploadService
 */
@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 : commons包裏提供的工具類
		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())
			{
				// 普通表單域: 直接讀取值
		    	// 指的是<input>,<select>,<textarea>輸入控件的值, 字符串類型
				String fieldValue = Streams.asString(fieldStream, "utf-8");
				printLog("表單域:" + fieldName + "=" + fieldValue);	
			}
		    else 
		    {
		    	// 文件域, 指<file>控件的值,指文件的數據
		    	// 生成唯一的文件名
		    	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);
		    }
		}
		return info.tmpFileName;
	}
	
	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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章