国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

JavaWeb實現文件上傳下載功能實例詳解

2019-11-26 13:35:50
字體:
來源:轉載
供稿:網友

在Web應用系統開發中,文件上傳和下載功能是非常常用的功能,今天來講一下JavaWeb中的文件上傳和下載功能的實現。

文件上傳概述

1、文件上傳的作用

例如網絡硬盤!就是用來上傳下載文件的。
在智聯招聘上填寫一個完整的簡歷還需要上傳照片呢。

2、文件上傳對頁面的要求

上傳文件的要求比較多,需要記一下:

必須使用表單,而不能是超鏈接
表單的method必須是POST,而不能是GET
表單的enctype必須是multipart/form-data
在表單中添加file表單字段,即<input type=”file” name=”xxx”/>

 <form action="${pageContext.request.contextPath }/FileUploadServlet"  method="post" enctype="multipart/form-data"> 用戶名:<input type="text" name="username"/><br/> 文件1:<input type="file" name="file1"/><br/> 文件2:<input type="file" name="file2"/><br/> <input type="submit" value="提交"/> </form>

3、比對文件上傳表單和普通文本表單的區別

通過httpWatch查看“文件上傳表單”和“普通文本表單”的區別。

文件上傳表單的enctype=”multipart/form-data”,表示多部件表單數據;
普通文本表單可以不設置enctype屬性:
        當method=”post”時,enctype的默認值為application/x-www-form-urlencoded,表示使用url編碼正文
        當method=”get”時,enctype的默認值為null,沒有正文,所以就不需要enctype了
對普通文本表單的測試:

<form action="${pageContext.request.contextPath }/FileUploadServlet" method="post"> 用戶名:<input type="text" name="username"/><br/> 文件1:<input type="file" name="file1"/><br/> 文件2:<input type="file" name="file2"/><br/> <input type="submit" value="提交"/></form>

通過httpWatch測試,查看表單的請求數據正文,我們發現請求中只有文件名稱,而沒有文件內容。也就是說,當表單的enctype不是multipart/form-data時,請求中不包含文件內容,而只有文件的名稱,這說明普通文本表單中input:file與input:text沒什么區別了。

對文件上傳表單的測試:

 <form action="${pageContext.request.contextPath }/FileUploadServlet"  method="post" enctype="multipart/form-data"> 用戶名:<input type="text" name="username"/><br/> 文件1:<input type="file" name="file1"/><br/> 文件2:<input type="file" name="file2"/><br/> <input type="submit" value="提交"/> </form>

通過httpWatch測試,查看表單的請求數據正文部分,發現正文部分是由多個部件組成,每個部件對應一個表單字段,每個部件都有自己的頭信息。頭信息下面是空行,空行下面是字段的正文部分。多個部件之間使用隨機生成的分隔線隔開。

文本字段的頭信息中只包含一條頭信息,即Content-Disposition,這個頭信息的值有兩個部分,第一部分是固定的,即form-data,第二部分為字段的名稱。在空行后面就是正文部分了,正文部分就是在文本框中填寫的內容。

文件字段的頭信息中包含兩條頭信息,Content-Disposition和Content-Type。Content-Disposition中多出一個filename,它指定的是上傳的文件名稱。而Content-Type指定的是上傳文件的類型。文件字段的正文部分就是文件的內容。

請注意,因為我們上傳的文件都是普通文本文件,即txt文件,所以在httpWatch中是可以正常顯示的,如果上傳的是exe、mp3等文件,那么在httpWatch看到的就是亂碼了

4、文件上傳對Servlet的要求

當提交的表單是文件上傳表單時,那么對Servlet也是有要求的。
首先我們要肯定一點,文件上傳表單的數據也是被封裝到request對象中的。

request.getParameter(String)方法獲取指定的表單字段字符內容,但文件上傳表單已經不在是字符內容,而是字節內容,所以失效。

這時可以使用request的getInputStream()方法獲取ServletInputStream對象,它是InputStream的子類,這個ServletInputStream對象對應整個表單的正文部分(從第一個分隔線開始,到最后),這說明我們需要的解析流中的數據。當然解析它是很麻煩的一件事情,而Apache已經幫我們提供了解析它的工具:commons-fileupload

可以嘗試把request.getInputStream()這個流中的內容打印出來,再對比httpWatch中的請求數據

public void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException { InputStream in = request.getInputStream(); String s = IOUtils.toString(in); System.out.println(s);}
-----------------------------7ddd3370ab2Content-Disposition: form-data; name="username"hello-----------------------------7ddd3370ab2Content-Disposition: form-data; name="file1"; filename="a.txt"Content-Type: text/plainaaa-----------------------------7ddd3370ab2Content-Disposition: form-data; name="file2"; filename="b.txt"Content-Type: text/plainbbb-----------------------------7ddd3370ab2--

commons-fileupload

為什么使用fileupload:

上傳文件的要求比較多,需要記一下:

       必須是POST表單;
       表單的enctype必須是multipart/form-data;
       在表單中添加file表單字段,即

Servlet的要求:

       不能再使用request.getParameter()來獲取表單數據
       可以使用request.getInputStream()得到所有的表單數據,而不是一個表單項的數據
       這說明不使用fileupload,我們需要自己來對request.getInputStream()的內容進行解析

1、fileupload概述

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

fileupload組件需要的JAR包有:

commons-fileupload.jar,核心包
commons-io.jar,依賴包

2、fileupload簡單應用

fileupload的核心類有:DiskFileItemFactory、ServletFileUpload、FileItem

使用fileupload組件的步驟如下:

//1.創建工廠類DiskFileItemFactory對象DiskFileItemFactory factory = new DiskFileItemFactory();//2.使用工廠創建解析器對象ServletFileUpload fileUpload = new ServletFileUpload(factory);//3.使用解析器來解析request對象List<FileItem> list = fileUpload.parseRequest(request);

DiskFileItemFactory 磁盤文件項工廠類

public DiskFileItemFactory(int sizeThreshold, File repository)
構造工廠時,指定內存緩沖區大小和臨時文件存放位置

public void setSizeThreshold(int sizeThreshold)
設置內存緩沖區大小,默認10K

public void setRepository(File repository)
設置臨時文件存放位置,默認System.getProperty(“java.io.tmpdir”).

內存緩沖區: 上傳文件時,上傳文件的內容優先保存在內存緩沖區中,當上傳文件大小超過緩沖區大小,就會在服務器端產生臨時文件

臨時文件存放位置: 保存超過了內存緩沖區大小上傳文件而產生臨時文件 ,產生臨時文件可以通過 FileItem的delete()方法刪除

FileItem 表示文件上傳表單中 每個數據部分

隆重介紹FileItem類,它才是我們最終要的結果。一個FileItem對象對應一個表單項(表單字段)。一個表單中存在文件字段和普通字段,可以使用FileItem類的isFormField()方法來判斷表單字段是否為普通字段,如果不是普通字段,那么就是文件字段了

注意事項:因為文件上傳表單采用編碼方式multipart/form-data 與傳統url編碼不同,所有getParameter ()方法不能使用 setCharacterEncoding()無法解決輸入項亂碼問題

ServletFileUpload 文件上傳核心類

3、簡單上傳示例

寫一個簡單的上傳示例:

       表單包含一個用戶名字段,以及一個文件字段;
      Servlet保存上傳的文件到uploads目錄,顯示用戶名,文件名,文件大小,文件類型。

第一步:

完成index.jsp,只需要一個表單。注意表單必須是post的,而且enctype必須是mulitpart/form-data的

<form action="${pageContext.request.contextPath }/FileUploadServlet"  method="post" enctype="multipart/form-data"> 用戶名:<input type="text" name="username"/><br/> 文件1:<input type="file" name="file1"/><br/> <input type="submit" value="提交"/></form>

第二步:完成FileUploadServlet

public void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException { // 因為要使用response打印,所以設置其編碼 response.setContentType("text/html;charset=utf-8"); // 創建工廠 DiskFileItemFactory dfif = new DiskFileItemFactory(); // 使用工廠創建解析器對象 ServletFileUpload fileUpload = new ServletFileUpload(dfif); try {  // 使用解析器對象解析request,得到FileItem列表  List<FileItem> list = fileUpload.parseRequest(request);  // 遍歷所有表單項  for(FileItem fileItem : list) {  // 如果當前表單項為普通表單項  if(fileItem.isFormField()) {   // 獲取當前表單項的字段名稱   String fieldName = fileItem.getFieldName();   // 如果當前表單項的字段名為username   if(fieldName.equals("username")) {   // 打印當前表單項的內容,即用戶在username表單項中輸入的內容   response.getWriter().print("用戶名:" + fileItem.getString() + "<br/>");   }  } else {//如果當前表單項不是普通表單項,說明就是文件字段   String name = fileItem.getName();//獲取上傳文件的名稱   // 如果上傳的文件名稱為空,即沒有指定上傳文件   if(name == null || name.isEmpty()) {   continue;   }   // 獲取真實路徑,對應${項目目錄}/uploads,當然,這個目錄必須存在   String savepath = this.getServletContext().getRealPath("/uploads");   // 通過uploads目錄和文件名稱來創建File對象   File file = new File(savepath, name);   // 把上傳文件保存到指定位置   fileItem.write(file);   // 打印上傳文件的名稱   response.getWriter().print("上傳文件名:" + name + "<br/>");   // 打印上傳文件的大小   response.getWriter().print("上傳文件大小:" + fileItem.getSize() + "<br/>");   // 打印上傳文件的類型   response.getWriter().print("上傳文件類型:" + fileItem.getContentType() + "<br/>");  }  } } catch (Exception e) {  throw new ServletException(e); }  }

文件上傳之細節

1、把上傳的文件放到WEB-INF目錄下

如果沒有把用戶上傳的文件存放到WEB-INF目錄下,那么用戶就可以通過瀏覽器直接訪問上傳的文件,這是非常危險的。

假如說用戶上傳了一個a.jsp文件,然后用戶在通過瀏覽器去訪問這個a.jsp文件,那么就會執行a.jsp中的內容,如果在a.jsp中有如下語句:Runtime.getRuntime().exec(“shutdown

主站蜘蛛池模板: 大城县| 会泽县| 广汉市| 桂林市| 贵州省| 中山市| 依安县| 泾阳县| 红安县| 高雄市| 辉县市| 五大连池市| 芒康县| 桃园市| 平南县| 封丘县| 高陵县| 德清县| 托里县| 永修县| 乐东| 罗定市| 渭南市| 历史| 铁岭县| 安龙县| 保亭| 改则县| 饶阳县| 苏尼特右旗| 岐山县| 衡东县| 泰和县| 临泉县| 米脂县| 鹤岗市| 三门县| 涪陵区| 临湘市| 黑龙江省| 兴义市|