1. 程式人生 > >檔案上傳該注意的問題

檔案上傳該注意的問題

檔案上傳該注意的基本問題:

(1)必須使用POST表單;

(2)表單的enctype必須是multipart/form-data;

(3)需要在表單中新增file表單欄位,即<input type=”file”…/>;

(4)request.getParameter(String)方法失效,因為request.getParameter(String)方法獲取指定的表單欄位字元內容,但檔案上傳表單已經不在是字元內容,而是位元組內容;

(5)可以使用request的getInputStream()方法獲取ServletInputStream物件,它是InputStream的子類,這個ServletInputStream物件對應整個表單的正文部分(從第一個分隔線開始,到最後),這說明我們需要的解析流中的資料。當然解析它是很麻煩的一件事情。

(6)確定我們需要使用fileupload來對request.getInputStream()的內容進行解析!commons-fileupload是由apache的commons元件提供的上傳元件,它最主要的工作就是幫我們解析request.getInputStream()。

fileupload元件需要的JAR包有:
------commons-fileupload.jar,核心包;
------commons-io.jar,依賴包。

fileupload的核心類有:DiskFileItemFactory,ServletFileUpload,FileItem。

————————————————————————————————————————————————

————————————————————————————————————————————————

檔案上傳該注意的細節問題:

(7)把上傳的檔案放到WEB-INF目錄下;如果沒有把使用者上傳的檔案存放到WEB-INF目錄下,那麼使用者就可以通過瀏覽器直接訪問上傳的檔案,這是非常危險的。

(8)上傳檔名稱可能是完整路徑;使用不同瀏覽器測試,其中IE6就會返回上傳檔案的完整路徑,就是需要處理這一問題。處理這一問題也很簡單,無論是否為完整路徑,我們都去擷取最後一個“\\”後面的內容就可以了。

(9)中文亂碼問題;
上傳檔名稱中包含中文:
當上傳的誰的名稱中包含中文時,需要設定編碼,commons-fileupload元件為我們提供了兩種設定編碼的方式:
------request.setCharacterEncoding(String):這種方式是我們最為熟悉的方式了;
------fileUpload.setHeaderEncdoing(String):這種方式的優先順序高與前一種。
上傳檔案的檔案內容包含中文:
通常我們不需關心上傳檔案的內容,因為我們會把上傳檔案儲存到硬碟上!也就是說,檔案原來是什麼樣子,到伺服器這邊還是什麼樣子!
但是如果你有這樣的需求,非要在控制檯顯示上傳的檔案內容,那麼你可以使用fileItem.getString(“utf-8”)來處理編碼。

(10)上傳檔案同名問題;使用uuid來解決,在每個檔案前加uuid;

(11)一個目錄不能存放過多的檔案;

(12)限制單個上傳檔案的大小;使用ServletFileUpload類的setFileSizeMax(long)就可以了。引數就是上傳檔案的上限位元組數,例如servletFileUpload.setFileSizeMax(1024*10)表示上限為10KB。

(13)上傳檔案的總大小限制;使用ServletFileUpload類的setSizeMax(long)方法即可;

(14)設定快取大小與臨時目錄;

DiskFileItemFactory dfif = new DiskFileItemFactory(1024*20, new File("F:\\temp"));
ServletFileUpload fileUpload = new ServletFileUpload(dfif);

fileupload會判斷檔案大小是否超出20KB,如果是那麼就把檔案儲存到臨時目錄temp上,如果沒有超出,那麼就儲存在記憶體中。

————————————————————————————————————————————————

————————————————————————————————————————————————

檔案上傳例項:

相關jar包:


jsp頁面:



上傳程式碼:

	public String add() throws UnsupportedEncodingException {
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		
		//request.setCharacterEncoding("utf-8");
		
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload sfu = new ServletFileUpload(factory);
		sfu.setFileSizeMax(2048 * 2048);

		try {
			List<FileItem> fileItemList = sfu.parseRequest(request);
			Map<String, String> map = new HashMap<String, String>();
			for (FileItem fileItem : fileItemList) {
				if (fileItem.isFormField()) {
					map.put(fileItem.getFieldName(),
							fileItem.getString("UTF-8"));
				}
			}
			post = CommonUtils.toBean(map, Post.class);
			post.setPid(CommonUtils.uuid());
			User user = (User) request.getSession().getAttribute("sessionUser");
			post.setUser(user);
			post.setPtime(new Date());

			// 得到儲存的目錄
			String savepath = ServletActionContext.getServletContext()
					.getRealPath("/post_img");
			// 得到檔名稱:給原來檔名稱新增uuid字首!避免檔名衝突
			String filename = CommonUtils.uuid() + "_"
					+ fileItemList.get(3).getName();

			/*
			 * 校驗檔案的副檔名
			 */
			if (!filename.toLowerCase().endsWith("jpg")) {
				request.setAttribute("msg", "您上傳的圖片不是JPG副檔名!");
				return "posting";
			}

			// 使用目錄和檔名稱建立目標檔案
			File destFile = new File(savepath, filename);
			// 儲存上傳檔案到目標檔案位置
			fileItemList.get(3).write(destFile);
			post.setPimg("post_img/" + filename);
			postService.add(post);
		} catch (Exception e) {
			if (e instanceof FileUploadBase.FileSizeLimitExceededException) {
				request.setAttribute("msg", "您上傳的檔案超出了1024KB");
				return "posting";
			}
		}

		return findByStatus();
	}