文件上傳——commons-fileUpload

文件上傳

  • 什麼是文件上傳

    將本地磁盤文件通過IO寫入到服務器的過程

  • 文件上傳的技術

    • Servlet3.0
    • JSPSmartUpload
    • FileUpload(這個是通用的技術,不像前面兩個需要對應引擎的支持,依託於環境)
    • 框架(其實框架中的文件上傳技術就是FileUpload技術的封裝)
  • 文件上傳的三要素

    • 表單的提交方式必須爲POST

    • 表單中需要有文件上傳表單項,必須有name屬性

      <input type="file" name="upload">

    • 表單的enctype屬性的值必須爲multipart/form-data

      • 如果沒有設置enctype屬性,那麼在請求中對應的upload只能獲取到文件的名字

      在請求頭中(只有表單提交的請求中才有content-Type
      在這裏插入圖片描述

      在請求體中
      在這裏插入圖片描述

      • 如果在form屬性中設置了enctype="multipart/form-data"

        在請求頭中
        在這裏插入圖片描述

        在請求體中(在火狐瀏覽器中才能看到)
        在這裏插入圖片描述

FileUpload

  • 使用fileUpload組件首先需要引入兩個jar包:

    • commons-fileUpload.jar
    • commons-io.jar

    下載

  • 編碼問題

    參考

    • 文件名亂碼(防止文件路徑中的中文亂碼)

      使用servletFileUpload.setHeaderEncoding("UTF-8");(通用方法,因爲上傳文件不一定是在servlet中)或者request.setCharacterEncoding("UTF-8")都可以。(原理:雖然在表單頁面是以utf-8的編碼提交的中文,但是在FileUpload組件中默認是用 ISO-8859-1來解碼,編碼和解碼的標準都不一樣,自然會出現亂碼)

    • 表單內容亂碼

      使用getString("utf-8")即可,也就是在獲取內容時,就可以設置編碼。

  • 如果表單中設置了enctype="multipart/form-data",那麼將不能用request.getParameter()來獲得請求參數的值。必須先獲得每個FileItem部分,再通過它的方法來獲取。

protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// 1、創建磁盤文件項工廠類對象
		// 不傳入參數,使用默認的緩存區大小(10kb)和默認的臨時文件存放的位置
		DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();

		// 2、創建核心解析類對象
		ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
		// 處理文件路徑中(文件名)爲中文出現亂碼的情況
		fileUpload.setHeaderEncoding("utf-8");

		try {
			// 3、解析請求對象,將請求分成幾個部分(FileItem)
			List<FileItem> list = fileUpload.parseRequest(request);

			// 4、遍歷集合獲得每個部分的對象
			for (FileItem fileItem : list) {
				
				// 判斷是否是普通表單項,是返回true,不是返回false
				if (fileItem.isFormField()) {
					// 獲得普通項的參數名
					String name = fileItem.getFieldName();
					// 獲得普通項的參數值,傳入解碼參數值的編碼,不傳默認是"ISO-8859-1"
					String value = fileItem.getString("UTF-8");

				} else {// 是文件上傳項

					// 獲得文件上傳項的參數名
					String name = fileItem.getFieldName();
					// 獲得文件上傳項的文件名
					String fileName = fileItem.getName();
					// 獲得文件上傳項的文件輸入流
					InputStream is = fileItem.getInputStream();

                    //生成唯一的文件名
					String exName=fileName.substring(fileName.lastIndexOf("."));
					String uuid=UUID.randomUUID().toString().replace("-","");
					String uuidFileName=uuid+exName;
                    
					// 獲得在服務器中保存這些上傳文件的磁盤絕對路徑(物理路徑)
					String path = this.getServletContext().getRealPath("/upload") + "\\" + uuidFileName;

					OutputStream os = new FileOutputStream(new File(path));
					int len = 0;
					byte[] b = new byte[1024];
					// 從文件的輸入流中讀取,再寫到服務器中指定的文件裏
					while ((len = is.read(b)) != -1) {
						os.write(b, 0, len);
					}
					os.close();
					is.close();
				}
			}
		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

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