如何實現網站中文件的上傳?——Javaweb

文件上傳

一、對錶單的一些要求

  1. 提交方法必須是post:method="post"
  2. 編碼屬性必須是multipart/form-data,也就是“多組件的表單數據”,即enctype="multipart/form-data"
    在這裏插入圖片描述
  3. 表單中需要添加文件表單項,即<input type="file" name="xxx" />

示例:

<body>
	<h1>上傳1</h1>
	<form action="<c:url value='/Upload1Servlet'/>" method="post" enctype="multipart/form-data">
		用戶名:<input type="text" name="username" /><br>
		照片:<input type="file" name="zhaopian" /><br>
		<input type="submit" value="上傳" />
	</form>
</body>

在這裏插入圖片描述

二、對servlet的一些要求

我們回憶一下我們以前用來接收表單傳遞過來的參數,使用的request.getParameter("xxx"),而這個方法在表單爲enctype="multipart/form-data"時,就作廢了。它永遠都會返回null。
那麼我們應該使用什麼樣的方法呢?是request.getInputStream(),返回值爲ServletInputStream類型,它會包含整個請求的體。

接下來我們研究一下多部件表單的體。

三、多部件表單請求體

  1. 分隔出多個部件,即一個表單項一個部件。
  2. 一個部件中自己包含請求頭和空行,以及請求體。
  3. 普通表單項:
    只有一個頭:Content-Disposition:包含name=“xxxx”,即表單項名稱。
    體就是表單項的值
  4. 文件表單項:
    有兩個頭:
    Content-Disposition:包含name="xxxx",即表單項名稱;還有一個filename="xxx",表示上傳文件的名稱
    Content-Type:它是上傳文件的MIME類型,例如:image/pjpeg,表示上傳的是圖片,其中是jpg擴展名的圖片。
    體就是上傳文件的內容

四、使用servlet獲取表單上傳的數據

我們寫一個相應的Servlet:

public class Upload1Servlet extends HttpServlet {
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");

		ServletInputStream in = request.getInputStream();
		String s = IOUtils.toString(in);
		System.out.println(s);	
	}
}

然後我們在頁面表單上輸入一些內容,然後在後臺查看會輸出什麼。
在這裏插入圖片描述
後臺內容:
在這裏插入圖片描述
我們可以清楚的看到上傳組件的部分構成。

五、commons-fileupload組件介紹

我們在上面的示例中獲取了表單上傳的數據,但是明顯的是,我們上傳的是一張圖片,後臺顯示出來的是一堆字符亂碼,這顯然是沒用的,我們就要想辦法把它變成圖片,這個時候應該怎麼做呢?

我們通過觀察,可以發現,請求體是有一定的固定格式的,我們很容易聯想到我們採取字符串分割一步步得到我們想要的內容,但是這樣有點太過於麻煩,這個時候我們應該怎麼辦呢?其實Apache已經幫我們提供瞭解析它的工具:commons-fileupload

fileupload是由apache的commons組件提供的上傳組件。它最主要的工作就是幫我們解析request.getInputStream()

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

這個小組件,它會幫我們解析request中的上傳數據,解析後的結果是一個表單項數據封裝到一個FileItem對象中。我們只需要調用FileItem的方法即可!

fileupload的核心類有:DiskFileItemFactoryServletFileUploadFileItem
使用fileupload組件的步驟如下:
1). 創建工廠類DiskFileItemFactory對象:DiskFileItemFactory factory = new DiskFileItemFactory();
2). 使用工廠創建解析器對象:ServletFileUpload fileUpload = new ServletFileUpload(factory);
3). 使用解析器來解析request對象:List<FileItem> list = fileUpload.parseRequest(request);

我們重點介紹一下FileItem類。一個FileItem對象對應一個表單項(表單字段)。一個表單中存在文件字段和普通字段,可以使用FileItem類的isFormField()方法來判斷表單字段是否爲普通字段,如果不是普通字段,那麼就是文件字段了。

  • String getName():獲取文件字段的文件名稱;
  • String getString():獲取字段的內容,如果是文件字段,那麼獲取的是文件內容,當然上傳的文件必須是文本文件;
  • String getFieldName():獲取字段名稱,例如:<input type=”text” name=”username”/>,返回的是username;
  • String getContentType():獲取上傳的文件的類型,例如:text/plain。
  • int getSize():獲取上傳文件的大小;
  • boolean isFormField():判斷當前表單字段是否爲普通文本字段,如果返回false,說明是文件字段;
  • InputStream getInputStream():獲取上傳文件對應的輸入流;
  • void write(File):把上傳的文件保存到指定文件中。

六、上傳的實例

接下來我們寫一下上傳的示例。

首先新建一個jsp,放入一個表單:

<body>
	<h1>上傳2</h1>
	<form action="<c:url value='/Upload2Servlet'/>" method="post" enctype="multipart/form-data">
		用戶名:<input type="text" name="username" /><br>
		照片:<input type="file" name="zhaopian" /><br>
		<input type="submit" value="上傳" />
	</form>
</body>

接下來是我們的servlet:

public class Upload2Servlet extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");

		/*
		 * 上傳的三步: 
		 * 1.創建工廠類; 
		 * 2.通過工廠類創建解析器; 
		 * 3.解析request,得到FileItem集合
		 * 4.遍歷FileItem集合,調用其API完成文件的保存
		 */
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload sfu = new ServletFileUpload(factory);
		try {
			List<FileItem> fileItemList = sfu.parseRequest(request);
			FileItem fi1 = fileItemList.get(0);
			FileItem fi2 = fileItemList.get(1);

			System.out.println("普通表單項演示:" + fi1.getFieldName() + "="
					+ fi1.getString("UTF-8"));

			System.out.println("文件表單項演示:");
			System.out.println("Content-Type:" + fi2.getContentType());
			System.out.println("size:" + fi2.getSize());
			System.out.println("filename:" + fi2.getName());

			// 保存文件
			File destFile = new File("E:/test.jpg");
			fi2.write(destFile);
			
		} catch (FileUploadException e) {
			throw new RuntimeException(e);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

我們在瀏覽器中打開網頁,並且選擇一張圖片:
在這裏插入圖片描述
我們看一下後臺出現了什麼:
在這裏插入圖片描述
我們再看一下我們的E盤下有沒有出現一個新的文件:
在這裏插入圖片描述
我們發現,功能全部符合我們的預期。


下一步,我們就要研究一下文件上傳中的一些其他的細節問題。


END.

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