Web基礎瞭解版12-上傳下載

来源:https://www.cnblogs.com/Open-ing/archive/2020/01/06/12151037.html
-Advertisement-
Play Games

上傳 兩個步驟: 用戶在頁面中選擇要上傳的文件,然後將請求提交到Servlet Servlet收到請求,解析用戶上傳的文件,然後將文件存儲到伺服器 上傳文件表單 <form action="Servlet" method="post" enctype="multipart/form-data"> < ...


上傳

兩個步驟:

  1. 用戶在頁面中選擇要上傳的文件,然後將請求提交到Servlet

  2. Servlet收到請求,解析用戶上傳的文件,然後將文件存儲到伺服器

上傳文件表單

<form action="Servlet" method="post" enctype="multipart/form-data">
    <input type="file" name="file" /><br /><br />
    <input type="submit" value="上傳" />
</form>

註意:

  • 表單的method屬性必須為post

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

  • 上傳文件的控制項是intput,type屬性為file

註意:Servelet

  • 當enctype="multipart/form-data" 時,再使用getParamter()獲取到內容永遠為空。
  • 需要引入解析請求中的參數和文件,這個工具就是commons-fileupload。

commons-fileupload

它的作用就是可以從request對象中解析出,用戶發送的請求參數和上傳文件的流。

commons-fileupload包依賴commons-io,兩個包需要同時導入

核心類:

  1. DiskFileItemFactory

    1. 工廠類,用於創建ServletFileUpload,設置緩存等

    2. 該類一般直接使用構造器直接創建實例

    3. 方法:

      • public void setSizeThreshold(int sizeThreshold):用於設置緩存文件的大小(預設值10kb)

      • public void setRepository(File repository):用於設置緩存文件位置(預設系統緩存目錄)

  2. ServletFileUpload

    1. 該類用於解析request對象從而獲取用戶發送的請求參數(包括普通參數和文件參數)

    2. 該類需要調用有參構造器創建實例,構造器中需要一個DiskFileItemFactory作為參數

    3. 方法:

      • public List<FileItem> parseRequest(HttpServletRequest request):解析request對象,獲取請求參數,返回的是一個List,List中保存的是一個FileItem對象,一個對象代表一個請求參數。

      • public void setFileSizeMax(long fileSizeMax):設置單個文件的大小限制,單位為B。如果上傳文件超出限制,會在parseRequest()拋出異常FileSizeLimitExceededException。

      • public void setSizeMax(long sizeMax):限制請求內容的總大小,單位為B。如果上傳文件超出限制,會在parseRequest()拋出異常SizeLimitExceededException。

  3. FileItem

    1. 該類用於封裝用戶發送的參數和文件,也就是用戶發送來的信息將會被封裝成一個FileItem對象,我們通過該對象獲取請求參數或上傳文件的信息。

    2. 該類不用我們手動創建,由ServletFileItem解析request後返回。

    3. 方法:

      • String getFieldName():獲取表單項的名字,也就是input當中的name屬性的值。

      • String getName():獲取上傳的文件名,普通的請求參數為null。

      • String getString(String encoding):獲取內容,encoding參數需要指定一個字元集。

        ① 若為文件,將文件的流轉換為字元串。

        ② 若為請求參數,則獲取請求參數的value。

      • boolean isFormField():判斷當前的FileItem封裝的是普通請求參數,還是一個文件。

        ① 如果為普通參數返回:true

        ② 如果為文件參數返回:false

      • String getContentType():獲取上傳文件的MIME類型

      • long getSize():獲取內容的大小

      • write():將文件上傳到伺服器

//創建工廠類
DiskFileItemFactory factory = new DiskFileItemFactory();
//創建請求解析器
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//設置上傳單個文件的的大小
fileUpload.setFileSizeMax(1024*1024*3);
//設置上傳總文件的大小
fileUpload.setSizeMax(1024*1024*3*10);
//設置響應內容的編碼
response.setContentType("text/html;charset=utf-8");
try {
    //解析請求信息,獲取FileItem的集合
    List<FileItem> items = fileUpload.parseRequest(request);
    //遍歷集合
    for (FileItem fileItem : items) {
        //如果是普通的表單項
        if(fileItem.isFormField()){
            //獲取參數名
            String fieldName = fileItem.getFieldName();
            //獲取參數值
            String value = fileItem.getString("utf-8");
            System.out.println(fieldName+" = "+value);
            //如果是文件表單項
        }else{
            //獲取文件名
            String fileName = fileItem.getName();
            //獲取上傳路徑
            String realPath = getServletContext().getRealPath("/WEB-INF/upload");
            //檢查upload文件夾是否存在,如果不存在則創建
            File f = new File(realPath);
            if(!f.exists()){
                f.mkdir();
            };
            //為避免重名生成一個uuid作為文件名的首碼
            String prefix = UUID.randomUUID().toString().replace("-", "");
            //將文件寫入到伺服器中
            fileItem.write(new File(realPath+"/"+prefix+"_"+fileName));
            //清除文件緩存
            fileItem.delete();
        }
  } }
catch (Exception e) { if(e instanceof SizeLimitExceededException){ //文件總大小超出限制 response.getWriter().print("上傳文件的總大小不能超過30M"); }else if(e instanceof FileSizeLimitExceededException){ //單個文件大小超出限制 response.getWriter().print("上傳單個文件的大小不能超過3M"); } } response.getWriter().print("上傳成功");

下載

下載文件的關鍵點:

  1. 伺服器以一個流的形式將文件發送給瀏覽器。

  2. 發送流的同時還需要設置幾個響應頭,來告訴瀏覽器下載的信息。

    • 具體響應頭如下:

      • Content-Type

        • 下載文件的MIME類型

        • 可以通過servletContext. getMimeType(String file)獲取

        • 也可以直接手動指定

        • 使用response.setContentType(String type);

        • 響應頭樣式:Content-Type: audio/mpeg

      • Content-Disposition

        • 下載文件的名字,主要作用是提供一個預設的用戶名

        • 通過response.setHeader("Content-Disposition", disposition)設置

        • 響應頭樣式:Content-Disposition: attachment; filename=xxx.mp3

      • Content-Length

        • 下載文件的長度,用於設置文件的長處(不必須)

        • 通過response. setContentLength(int len)設置。

        • 設置後樣式:Content-Length: 3140995

  3. 接下來需要以輸入流的形式讀入硬碟上的文件

    • FileInputStream is = new FileInputStream(file);

    • 這個流就是我們一會要發送給瀏覽器的內容

  4. 通過response獲取一個輸出流,並將文件(輸入流)通過該流發送給瀏覽器

    • 獲取輸出流:ServletOutputStream out = response.getOutputStream();

    • 通過輸出流向瀏覽器發送文件(不要忘了關閉輸入流)

步驟演示

以下步驟都是在同一個Servlet的doGet()方法中編寫的

1.獲取文件的流:

String realPath = getServletContext().getRealPath("/WEB-INF/mp3/中國話.mp3");
//獲取文件的File對象
File file = new File(realPath);
//獲取文件的輸入流
FileInputStream in = new FileInputStream(file);

 

2.獲取頭信息:

//獲取文件的MIME信息
String contentType = getServletContext().getMimeType(realPath);
//設置下載文件的名字
String filename = "zhongguohua.mp3";
//創建Content-Disposition信息
String disposition = "attachment; filename="+ filename ;
//獲取文件長度
long size = file.length();

 

3.設置頭信息

//設置Content-Type
response.setContentType(contentType);
//設置Content-Disposition
response.setHeader("Content-Disposition", disposition);
//設置文件長度
response.setContentLength((int)size);

 

4.發送文件

//通過response獲取輸出流,用於向瀏覽器輸出內容
ServletOutputStream out = response.getOutputStream();
//將文件輸入流通過輸出流輸出
byte[] b = new byte[1024];
int len = 0;
while((len=is.read(b))> 0){
    out.write(b, 0, len);
}
//最後不要忘記關閉輸入流,輸出流由Tomcat自己處理,我們不用手動關閉
is.close();

 

亂碼

中文文件名會出現亂碼問題。解決此問題的方法很簡單,在獲取文件名之後為文件名進行編碼:

filename = java.net.URLEncoder.encode(filename,"utf-8");

火狐瀏覽器比較特殊需要特殊處理一下。

1.先要獲取客戶端信息(通過獲取請求頭中的User-Agent信息)

String ua = request.getHeader("User-Agent");

 

2.然後判斷瀏覽器版本,做不同的處理

//判斷客戶端是否為火狐
if(ua.contains("Firefox")){
    //若為火狐使用BASE64編碼
    filename = "=?utf-8?B?"+new BASE64Encoder().encode(filename.getBytes("utf-8"))+"?=";
}else{
    //否則使用UTF-8
    filename = URLEncoder.encode(filename,"utf-8");
}

 

String string = new String("你好.jpg".getBytes("gbk"), "iso8859-1");

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 場景 效果 註: 博客: https://blog.csdn.net/badao_liumang_qizhi 關註公眾號 霸道的程式猿 獲取編程相關電子書、教程推送與免費下載。 實現 將需要滾動查看的照片複製到res/drawable下 這裡只准備了兩張bg01.jpg和bg02.jpg 在滾動時需 ...
  • 場景 效果 註: 博客: https://blog.csdn.net/badao_liumang_qizhi 關註公眾號 霸道的程式猿 獲取編程相關電子書、教程推送與免費下載。 實現 將佈局改為LinearLayout,並通過android:orientation="vertical">設置為垂直布 ...
  • 場景 效果 註: 博客: https://blog.csdn.net/badao_liumang_qizhi 關註公眾號 霸道的程式猿 獲取編程相關電子書、教程推送與免費下載。 實現 將佈局改為LinearLayout,並通過android:orientation="vertical">設置為垂直布 ...
  • 效果 核心代碼 >方法 /** * @description 選擇日期彈出框 * @param listener 選擇日期確定後執行的介面 * @param curDate 當前顯示的日期 * @return * @author wqy * @time 2020-1-6 14:23 */ publi ...
  • 一、焦點圖 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>D156_PictureOfFocus</title> <style> *{ margin:0; padding:0; } div{ width: ...
  • 本周再來翻譯一些技術文章,本次預計翻譯三篇文章如下: "04.[譯]使用Nuxt生成靜態網站" ( "Generate Static Websites with Nuxt" ) "05.[譯]Web網頁內容是如何影響電池功耗的" ( "How Web Content Can Affect Power ...
  • html中標簽有很多,每一種標簽都有著不同的用處,下麵這篇文章給大家總結html常用的標簽,每一種標簽都會跟隨一個例子,話不多說,讓我們來看看具體內容。 我的學習交流群web前端學習交流群 <font> 字體標簽,用於展示效果中修飾文字樣式 <font 屬性名=”屬性值”>文字</font> siz ...
  • 標簽、事件、屬性 xss的攻擊原理就是前端被插入了惡意的js代碼,下麵展示大部分可以執行js的標簽、事件、屬性; 標簽(label) Chrome下srcdoc屬性 JS代碼註入,意味著無需\ html ?query%5Border_No%5D=&query%5Bm obile%5D=%27%2ba ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...