日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java Web之文件的上传及下载

發(fā)布時間:2025/3/19 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java Web之文件的上传及下载 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、文件的上傳

  1、 簡介

    > 將一個客戶端的本地的文件發(fā)送到服務(wù)器中保存。

    > 上傳文件是通過流的形式將文件發(fā)送給服務(wù)器。

  2、表單的設(shè)置

      1.向服務(wù)器上傳一個文件時,表單要使用post請求。

      2.表單的默認屬性enctype="application/x-www-form-urlencoded"

          - 這個屬性的意思是請求體中的內(nèi)容將會使用URL編

      3. 上傳文件的表單enctype需要設(shè)置為 multipart/form-data

          - multipart/form-data表示的是表單是一個多部件的表單

          - 如果類型設(shè)置為它,則我們的每一個表單項都會作為一個單獨的部件發(fā)送給服務(wù)器。

          - 多個部件之間使用類似 -----------------------------7df2d08c0892 分割符來分開

      4. 當(dāng)表單設(shè)置為multipart/form-data時,我們request.getParameter()將失效,我們不能再通過該方法獲取請求參數(shù)。

  3、 FileUpload

      1. 我們一般情況下使用commons-fileupload-1.3.1.jar這個工具來解析多部件請求。

      2. fileupload 依賴 commons-io 所以我們要是Filtupload需要同時導(dǎo)入io包。

      3. 核心類:

          DiskFileItemFactory

            - 工廠類,用于構(gòu)建一個解析器實例。

          ServletFileUpload

            - 解析器類,通過該類實例來解析request中的請求信息。

          FileItem

            - 工具會將我們請求中每一個部件,都封裝為一個FileItem對象,處理文件上傳時,只需要調(diào)用該對象的方法

            - 方法:
                boolean isFormField() --> 當(dāng)前表單項是否是一個普通表單項,true是普通表單項, false是文件表單項

                String getContentType() --> 返回的是文件的類型,是MIME值:如image/jpeg,text/html

                String getFieldName() --> 獲取表單項的name屬性值

                String getName() --> 獲取上傳的文件的名字

                long getSize() --> 獲取文件的大小

                String getString(String encoding) --> 獲取表單項的value屬性值,需要接受一個編碼作為參數(shù)。

                void write(File file) --> 將表單項中的內(nèi)容寫入到磁盤中

      4、 使用步驟:

            1.獲取工廠類實例

            2.獲取解析器類實例

            3.解析request獲取FileItem

   代碼演示:

1 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 2 //1、創(chuàng)建工廠類對象 3 DiskFileItemFactory factory=new DiskFileItemFactory(); 4 //2、創(chuàng)建解析器類對象 5 ServletFileUpload upload=new ServletFileUpload(factory); 6 7 upload.setFileSizeMax(1024*50); //設(shè)置單個文件的大小為50K 8 upload.setSizeMax(1024*120); //設(shè)置上傳總文件的大小為120K 9 10 List<FileItem> list=new ArrayList<FileItem>(); 11 try { 12 //3、解析請求部件 13 list=upload.parseRequest(request); 14 for(FileItem fileItem:list){ 15 if(fileItem.isFormField()){ //判斷是否為普通表單項 16 String name=fileItem.getFieldName(); //獲取name屬性名 17 String value=fileItem.getString(); //獲取name屬性值 18 System.out.println(name+":"+value); 19 }else { //文件表單項 20 long size = fileItem.getSize(); //獲取文件大小 21 if(size>0){ 22 String name=fileItem.getFieldName(); //獲取name屬性名 23 String fileName=fileItem.getName(); //獲取文件名 24 if(fileName.contains("\\")){ //截取文件名 25 fileName=fileName.substring(fileName.lastIndexOf("\\")+1); 26 } 27 //解決文件名重復(fù)問題,使用uuid,在文件名前加上uuid,防止重復(fù) 28 String uuid=UUID.randomUUID().toString().replace("-",""); 29 fileName=uuid+"_"+fileName;//加上"_",便于截串 30 String contentType = fileItem.getContentType(); //獲取文件類型 31 32 System.out.println("name屬性名為:"+name); 33 System.out.println("文件名為:"+fileName); 34 System.out.println("文件類型為:"+contentType); 35 System.out.println("文件大小為:"+size); 36 37 ServletContext context=request.getServletContext(); //獲取上下文對象 38 String realPath = context.getRealPath("/upload"); //獲取文件真實路徑 39 File file=new File(realPath); //按照路徑創(chuàng)建目錄 40 if(!file.exists()){ //目錄不存在 41 file.mkdirs(); //創(chuàng)建目錄 42 } 43 //將上傳的文件保存到指定目錄下 44 fileItem.write(new File(realPath+"/"+fileName)); 45 } 46 } 47 } 48 } catch(FileSizeLimitExceededException e){ 49 request.setAttribute("msg", "單個文件超出50k"); 50 request.getRequestDispatcher("/upload.jsp").forward(request, response); 51 } catch (SizeLimitExceededException e) { 52 request.setAttribute("msg", "文件大小超出120k"); 53 request.getRequestDispatcher("/upload.jsp").forward(request, response); 54 }catch (Exception e) { 55 e.printStackTrace(); 56 } 57 } 文件上傳

  4、 細節(jié)

      1.第一個問題:> 部分瀏覽器會將文件的完整路徑作為文件名發(fā)送。       

        C:\Users\lilichao\Desktop\day20\圖片\蒙娜麗莎.jpg

        > 像這類文件名我們需要截取一下字符串,只獲取名字這部分,而不需要獲取路徑部分的信息。

        通過如下代碼對文件名進行截取字符串的操作

1    if(name.contains("\\")){ //如果包含則截取字符串    2       name = name.substring(name.lastIndexOf("\\")+1); 3    }

      2.第二個問題上傳的文件有可能出現(xiàn)重名,后上傳的文件會將先上傳的文件覆蓋。

        > 解決:給文件名加一個唯一的前綴。

           唯一標(biāo)識_fennu.jpg

           UUID_fennu.jpg

1     //解決文件名重復(fù)問題,使用uuid,在文件名前加上uuid,防止重復(fù) 2 String uuid=UUID.randomUUID().toString().replace("-",""); 3 fileName=uuid+"_"+fileName;//加上"_",便于截串

?

      3.第三個問題有些情況需要限制上傳文件的大小。

        - 設(shè)置單個文件大小為50KB:

            fileUpload.setFileSizeMax(1024*50);

              - 設(shè)置完單個文件大小限制以后,一旦上傳的文件超過限制,則會拋出如下異常:

            FileSizeLimitExceededException

              -所以可以對該異常進行捕獲,當(dāng)出現(xiàn)該異常時則設(shè)置一個錯誤消息。

        - 設(shè)置多個文件的總大小為150KB

            fileUpload.setSizeMax(1024*150);

              - 當(dāng)多個文件的大小超出范圍時,會拋出如下異常

            SizeLimitExceededException

      4.第四個問題?當(dāng)用戶上傳一個空的文件,依然會將文件保存到硬盤上。

          > 在保存文件應(yīng)該先對文件的大小進行判斷,如果size為0,則不處理。

二、文件的下載

  1、 簡介

      > 將服務(wù)器中的文件下載到本地。

      > 一般情況下資源所在的鏈接發(fā)送給瀏覽器,瀏覽器就會自動下載。

        但是當(dāng)瀏覽器支持當(dāng)前文件的格式,瀏覽器會自動打開文件,而不會彈出下載窗口。

      > 直接將資源放在項目的目錄下,瀏覽器可以直接訪問到資源。

        所以一般我們下載的資源不能讓瀏覽器直接訪問到。

  2、 下載所需要的內(nèi)容

      1.獲取到文件的流

      2.設(shè)置兩個響應(yīng)頭

  3、 下載相關(guān)的兩個響應(yīng)頭

      1) 文件類型 Content-Type --> 文件的MIME類型

        Content-Type:告訴瀏覽器文件的類型,需要設(shè)置一個MIME值

          response.setContent-Type("MIME值")

        通過servletContext.getMimeType(path)方法可以直接獲取文件的MIME類型

      2) 下載文件的信息 Content-Disposition --> attachment; filename=文件名

          Content-Disposition告訴瀏覽器如何處理文件,

          attachment 告訴瀏覽器這個文件是一個附件的形式發(fā)給你的,需要你做下載的操作

          filename 告訴瀏覽器下載文件的名字

      3) 亂碼的問題,當(dāng)將文件的名字設(shè)置為中文,瀏覽器正常顯示文件的名字。

          因為從服務(wù)器向瀏覽器發(fā)送中文時,需要對內(nèi)容進行URL編碼。

            > 大部分瀏覽器使用如下方式即可解決亂碼問題:URLEncoder.encode(fileName, "utf-8");

            > 但是火狐默認以Base64來解碼的,所以要為火狐單獨處理。

        1. 可以使用如下代碼來判斷瀏覽器的類型,然后進行不同的編碼處理

1   String ua=request.getHeader("User-Agent");//獲得請求頭瀏覽器信息 2   //判斷當(dāng)前瀏覽器是否為火狐 3   if(ua.contains("Firefox")){ 4     //是火狐瀏覽器,使用BASE64編碼 5     fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes("utf-8"))+"?="; 6   }else{ 7     //給文件名進行URL編碼 8     //URLEncoder.encode()需要兩個參數(shù),第一個參數(shù)時要編碼的字符串,第二個是編碼所采用的字符集 9     fileName = URLEncoder.encode(fileName, "utf-8"); 10   }

      ? 2. ?還有一種不太講理的方式,誰問跟誰急。反正好使

          - 向?qū)⒆址胓bk進行解碼,然后在使用iso8859-1進行編碼

             fileName = new String(fileName.getBytes("gbk"),"iso8859-1");
  代碼演示:

1 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 2 //獲取Servlet上下文參數(shù) 3 ServletContext context=request.getServletContext(); 4 String fileName="風(fēng)吹麥浪.mp3"; 5 //獲取要下載文件的真實路徑 6 String path = context.getRealPath("/WEB-INF/"+fileName); 7 //獲取要下載文件的MIME值類型 8 String mime=context.getMimeType(path); 9 10 //創(chuàng)建輸入流,讀取指定位置的文件 11 FileInputStream in=new FileInputStream(path); 12 //設(shè)置響應(yīng)頭ContentType類型 13 response.setContentType(mime); 14 15 //1、根據(jù)不同瀏覽器,設(shè)置文件名編碼格式(必須在設(shè)置Content-Disposition之前) 16 // String ua=request.getHeader("User-Agent");//獲得請求頭瀏覽器信息 17 // if(ua.contains("Firefox")){ 18 // fileName="=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes("utf-8"))+"?="; 19 // }else { 20 // fileName=URLEncoder.encode(fileName, "utf-8"); 21 // } 22 23 //2、第二種方法,一般不會出錯 24 fileName = new String(fileName.getBytes("gbk"),"iso8859-1"); 25 26 //設(shè)置響應(yīng)頭Content-Disposition 27 response.setHeader("Content-Disposition", "attachment; filename="+fileName); 28 29 //創(chuàng)建輸出流 30 ServletOutputStream out=response.getOutputStream(); 31 //使用工具,將輸入流中的數(shù)據(jù)copy到輸出流中 32 IOUtils.copy(in, out); 33 //關(guān)閉輸入流 34 in.close(); 35 } 文件下載

?

轉(zhuǎn)載于:https://www.cnblogs.com/java-zmj/p/7928731.html

總結(jié)

以上是生活随笔為你收集整理的Java Web之文件的上传及下载的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。