JavaWeb文件上傳和下載

      網(wǎng)友投稿 1017 2025-03-31

      在如今的互聯(lián)網(wǎng)時(shí)代,人們?cè)絹?lái)越喜歡將自己的數(shù)據(jù)存放到互聯(lián)網(wǎng)上,于是便誕生了很多類型的軟件,比如360網(wǎng)盤,百度網(wǎng)盤,云盤之類的。所以說(shuō),文件上傳和下載的功能是現(xiàn)在非常主流的一個(gè)功能,應(yīng)用十分廣泛。

      那現(xiàn)在,我們就來(lái)學(xué)習(xí)一下,在web中,如何去實(shí)現(xiàn)文件上傳和下載!

      實(shí)現(xiàn)web開發(fā)中的文件上傳功能,需完成如下二步操作:

      在web頁(yè)面中添加上傳輸入項(xiàng)

      在servlet中讀取上傳文件的數(shù)據(jù),并保存到服務(wù)器硬盤中。

      如何在web頁(yè)面中添加上傳輸入項(xiàng)?

      標(biāo)簽用于在web頁(yè)面中添加文件上傳輸入項(xiàng),設(shè)置文件上傳輸入項(xiàng)時(shí)須注意:

      1、必須要設(shè)置input輸入項(xiàng)的name屬性,否則瀏覽器將不會(huì)發(fā)送上傳文件的數(shù)據(jù)。

      2、必須把form的enctype屬值設(shè)為multipart/form-data.設(shè)置該值后,瀏覽器在上傳文件時(shí),將把文件數(shù)據(jù)附帶在http請(qǐng)求消息體中,并使用MIME協(xié)議對(duì)上傳的文件進(jìn)行描述,以方便接收方對(duì)上傳數(shù)據(jù)進(jìn)行解析和處理。

      3、表單的提交方式要是post

      這是頁(yè)面的實(shí)現(xiàn),接下來(lái)是具體功能的實(shí)現(xiàn)。

      如何在Servlet中讀取文件上傳數(shù)據(jù),并保存到本地硬盤中?

      Request對(duì)象提供了一個(gè)getInputStream方法,通過(guò)這個(gè)方法可以讀取到客戶端提交過(guò)來(lái)的數(shù)據(jù)。但由于用戶可能會(huì)同時(shí)上傳多個(gè)文件,在servlet端編程直接讀取上傳數(shù)據(jù),并分別解析出相應(yīng)的文件數(shù)據(jù)是一項(xiàng)非常麻煩的工作。

      知道了原理,我們現(xiàn)在來(lái)編寫一個(gè)案例。

      新建web項(xiàng)目。

      創(chuàng)建upload.jsp文件。

      <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> Insert title here

      用戶名:
      上傳文件:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      然后我們創(chuàng)建一個(gè)UploadServlet

      package cn.itcast.servlet; import java.io.IOException; import java.io.InputStream; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class UploadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //request提供getInputStream,用來(lái)獲得請(qǐng)求體 InputStream in = request.getInputStream(); int temp; while((temp = in.read()) != -1){ System.out.write(temp); } System.out.flush(); in.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      這樣代碼我們就編寫完成了,然后我們準(zhǔn)備一個(gè)info.txt文件,用于文件上傳。

      Defines methods that all servlets must implement. A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol. To implement this interface, you can write a generic servlet that extends javax.servlet.GenericServlet or an HTTP servlet that extends javax.servlet.http.HttpServlet. This interface defines methods to initialize a servlet, to service requests, and to remove a servlet from the server. These are known as life-cycle methods and are called in the following sequence: The servlet is constructed, then initialized with the init method. Any calls from clients to the service method are handled. The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized. In addition to the life-cycle methods, this interface provides the getServletConfig method, which the servlet can use to get any startup information, and the getServletInfo method, which allows the servlet to return basic information about itself, such as author, version, and copyright.

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      準(zhǔn)備工作已經(jīng)做好了,現(xiàn)在我們來(lái)試著運(yùn)行一下。

      現(xiàn)在我們通過(guò)request對(duì)象的getInputStream方法獲得了整個(gè)請(qǐng)求體的信息,但是,請(qǐng)求體里不僅僅是有info.txt文件的文本內(nèi)容,還有其它的一些參數(shù)信息,我們現(xiàn)在該如何將文本內(nèi)容拿到呢?關(guān)鍵的地方就在于這個(gè)分割線,但有同學(xué)可能會(huì)質(zhì)疑,如果我的文本內(nèi)容中就有這么一段分割線的信息呢?這就要看看我們的請(qǐng)求頭信息了。

      該請(qǐng)求頭的參數(shù)即是分割線。

      雖然,文本內(nèi)容和產(chǎn)生的分割線相同的情況也可能會(huì)發(fā)生,但是,幾率是非常小的,幾乎可以忽略不計(jì)。

      現(xiàn)在,我們就可以通過(guò)分割線來(lái)對(duì)請(qǐng)求體進(jìn)行分割。

      然后判斷分割出來(lái)的各個(gè)部分中,哪個(gè)為文本內(nèi)容。判斷依據(jù):判斷哪個(gè)部分含有fliename和content-type,證明其是文本內(nèi)容。

      原理就是這樣,具體我就不實(shí)現(xiàn)了,感興趣的可以自己寫一寫。

      一路下來(lái),你會(huì)發(fā)現(xiàn)自己實(shí)現(xiàn)文件上傳和下載其實(shí)是非常麻煩的,好在我們有現(xiàn)成的工具可以使用。

      為方便用戶處理文件上傳數(shù)據(jù),Apache 開源組織提供了一個(gè)用來(lái)處理表單文件上傳的一個(gè)開源組件( Commons-fileupload ),該組件性能優(yōu)異,并且其API使用極其簡(jiǎn)單,可以讓開發(fā)人員輕松實(shí)現(xiàn)web文件上傳功能,因此在web開發(fā)中實(shí)現(xiàn)文件上傳功能,通常使用Commons-fileupload組件實(shí)現(xiàn)。

      需要知道的是,在Servlet3.0之后,Servlet程序本身就支持文件上傳。

      但我們還是需要來(lái)學(xué)習(xí)一下該jar的使用。下面是jar包的-。

      鏈接:https://pan.baidu.com/s/1F-fS7JgfilSF9bLA8iVQuQ

      提取碼:3kfh

      復(fù)制這段內(nèi)容后打開百度網(wǎng)盤手機(jī)App,操作更方便哦

      下載完成后,將jar包添加到我們的項(xiàng)目中。

      然后我簡(jiǎn)單介紹一下使用方法。

      1、通過(guò)工廠DiskFileItemFactory構(gòu)造解析器ServletFileUpload

      2、用解析器將請(qǐng)求體的各個(gè)部分以分割線進(jìn)行分割,得到多個(gè)部分,每個(gè)部分就是一個(gè)FileItem

      3、FileItem中提供了很多API,可以通過(guò)isFormField來(lái)判斷該部分是不是一個(gè)文件上傳項(xiàng)

      4、如果是文件上傳項(xiàng),可以通過(guò)getInputStream獲得上傳文件的內(nèi)容,通過(guò)getName獲得上傳文件的名字

      5、如果不是文件上傳項(xiàng),可以通過(guò)getFieldName獲得上傳表單項(xiàng)的name屬性,通過(guò)getString獲得上傳表單項(xiàng)的value屬性

      接下來(lái),我們借助第三方API來(lái)實(shí)現(xiàn)一下文件上傳。

      package cn.itcast.servlet; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; public class UploadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //request提供getInputStream,用來(lái)獲得請(qǐng)求體 // InputStream in = request.getInputStream(); // int temp; // while((temp = in.read()) != -1){ // System.out.write(temp); // } // System.out.flush(); // in.close(); //步驟一 構(gòu)造工廠 DiskFileItemFactory factory = new DiskFileItemFactory(); //步驟二 獲得解析器 ServletFileUpload upload = new ServletFileUpload(factory); //步驟三 對(duì)請(qǐng)求體內(nèi)容進(jìn)行解析 try { List fList = upload.parseRequest(request); //步驟四 遍歷集合 for(FileItem fileItem : fList){ //步驟五 判斷每個(gè)fileItem是不是文件上傳項(xiàng) if(fileItem.isFormField()){ //不是上傳文件 String name = fileItem.getFieldName(); String value = fileItem.getString(); System.out.println("普通form項(xiàng):" + name + "---" + value); }else{ //是上傳文件 String fileName = fileItem.getName(); //解決老版本瀏覽器文件路徑問(wèn)題 if(fileName.contains("\")){ fileName = fileName.substring(fileName.lastIndexOf("\") + 1); } InputStream in = fileItem.getInputStream();//得到的是文件內(nèi)容 System.out.println("文件上傳項(xiàng):" + fileName); //將內(nèi)容寫入文件 File file = new File("C:\Users\Administrator\Desktop\info_test.txt"); if(!file.exists()){ //文件不存在,創(chuàng)建文件 file.createNewFile(); } FileOutputStream out = new FileOutputStream(file); int len; while((len = in.read()) != -1){ out.write(len); } in.close(); out.close(); } } } catch (FileUploadException e) { e.printStackTrace(); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      JavaWeb之文件上傳和下載

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      然后運(yùn)行項(xiàng)目,在桌面就會(huì)產(chǎn)生一個(gè)新的文件,打開文件,發(fā)現(xiàn)文本內(nèi)容被成功寫入到了該文件中。

      這樣,一個(gè)非常簡(jiǎn)單的文件上傳案例就完成了。接下來(lái),我們對(duì)FileUpload工具的核心類進(jìn)行一個(gè)詳細(xì)的學(xué)習(xí)。

      DiskFileItemFactory 是創(chuàng)建 FileItem 對(duì)象的工廠,這個(gè)工廠類常用方法:

      public DiskFileItemFactory(int sizeThreshold, java.io.File repository)

      構(gòu)造函數(shù)

      public void setSizeThreshold(int sizeThreshold)

      設(shè)置內(nèi)存緩沖區(qū)的大小,默認(rèn)值為10K。當(dāng)上傳文件大于緩沖區(qū)大小時(shí), fileupload組件將使用臨時(shí)文件緩存上傳文件。

      public void setRepository(java.io.File repository)

      指定臨時(shí)文件目錄,默認(rèn)值為System.getProperty(“java.io.tmpdir”).

      注意:上傳文件優(yōu)先保存在內(nèi)容緩沖區(qū),當(dāng)內(nèi)存緩沖區(qū)不夠用,就會(huì)在硬盤上產(chǎn)生臨時(shí)文件,臨時(shí)文件保存在指定的臨時(shí)文件目錄中,臨時(shí)文件與源文件的內(nèi)容相同。

      然后是如何解決中文亂碼問(wèn)題,有同學(xué)可能會(huì)問(wèn),post請(qǐng)求處理亂碼問(wèn)題,使用requeset.setCharacterEncoding(“utf-8”)不就行了嗎,在這里它還真就不行了,不信的話可以自己試一試。其實(shí),在解析器中提供了API來(lái)解決這個(gè)中文亂碼問(wèn)題。你只需要使用ServletFieUpload對(duì)象調(diào)用setHeaderEncoding(“utf-8”)方法即可解決。

      還有一個(gè)問(wèn)題,就是隨著請(qǐng)求次數(shù)的增加,服務(wù)器的臨時(shí)文件會(huì)越來(lái)越多,這加重了服務(wù)器的負(fù)擔(dān),所以當(dāng)上傳文件完成時(shí),我們應(yīng)該刪除臨時(shí)文件。在程序的最后調(diào)用FileItem對(duì)象的delete()方法即可刪除。

      ServletFileUpload 負(fù)責(zé)處理上傳的文件數(shù)據(jù),并將表單中每個(gè)輸入項(xiàng)封裝成一個(gè) FileItem 對(duì)象中。常用方法有:

      boolean isMultipartContent(HttpServletRequest request)

      判斷上傳表單是否為multipart/form-data類型

      List parseRequest(HttpServletRequest request)

      解析request對(duì)象,并把表單中的每一個(gè)輸入項(xiàng)包裝成一個(gè)fileItem 對(duì)象,并返回一個(gè)保存了所有FileItem的list集合。

      setFileSizeMax(long fileSizeMax)

      設(shè)置單個(gè)上傳文件的最大值

      setSizeMax(long sizeMax)

      設(shè)置上傳文件總量的最大值

      setHeaderEncoding(java.lang.String encoding)

      設(shè)置編碼格式

      setProgressListener(ProgressListener pListener)

      實(shí)時(shí)監(jiān)聽文件上傳狀態(tài)

      注意:如果是文件上傳,我們可以通過(guò)getFieldName()方法獲得文件名,如果不是文件上傳,我們可以通過(guò)getName()方法獲得表單項(xiàng)的name屬性,getValue()方法獲得表單項(xiàng)的值,其中,getValue()方法如果獲得的是中文數(shù)據(jù),會(huì)產(chǎn)生亂碼,此時(shí),基本的處理亂碼問(wèn)題的API都不管用,但也不用擔(dān)心,我們可以使用它提供的API。它重載了一個(gè)getString(java.lang.String encoding)方法,只需要將utf-8作為參數(shù)傳入即可。

      Java web前端

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:部署云網(wǎng)盤
      下一篇:使用網(wǎng)盤搭建svn服務(wù)器詳解步驟
      相關(guān)文章
      国产亚洲AV夜间福利香蕉149| 亚洲av日韩av综合| 亚洲午夜福利在线视频| 久久亚洲精品无码VA大香大香| 亚洲av日韩av无码| 亚洲AV无码国产精品麻豆天美| 亚洲国产精品成人精品无码区 | 亚洲欧洲国产精品香蕉网| 亚洲&#228;v永久无码精品天堂久久 | 久久亚洲精品成人av无码网站| 亚洲AV本道一区二区三区四区 | 亚洲AV一区二区三区四区| 精品亚洲成在人线AV无码| 久久亚洲精品专区蓝色区| 久久亚洲精品专区蓝色区| 亚洲日韩精品国产3区| 亚洲啪AV永久无码精品放毛片| 亚洲男人的天堂网站| 亚洲av无码成人精品区一本二本| 亚洲av乱码中文一区二区三区| 无码天堂亚洲国产AV| 亚洲国产综合精品一区在线播放| 亚洲性日韩精品国产一区二区| 精品国产人成亚洲区| 亚洲成色www久久网站夜月| 亚洲第一区香蕉_国产a| 亚洲自偷自拍另类12p| 亚洲国产精品成人精品小说| 2020天堂在线亚洲精品专区| 亚洲精品国产suv一区88| 国产大陆亚洲精品国产| 亚洲视频人成在线播放| 亚洲精品高清无码视频| 亚洲国产美国国产综合一区二区| 亚洲精品中文字幕无乱码| 激情亚洲一区国产精品| 亚洲av无码一区二区三区天堂| 国产青草亚洲香蕉精品久久| 中文字幕亚洲激情| 久久精品亚洲视频| 亚洲制服丝袜一区二区三区|