天天看點

SpringBoot 檔案上傳和下載下傳(一)

作者:JU幫

在現在微服務系統中,檔案的上傳和下載下傳可以說是正常操作,這篇文章帶領大家一起探究一下 SpringBoot 中檔案是如何上傳和下載下傳的。

在正式探究檔案上傳和下載下傳之前,需要先學習幾個 HTTP 相關的基本知識,如果想深入學習 HTTP,可以檢視 https://developer.mozilla.org/zh-CN/docs/Web/HTTP 中相關的文章。

MIME 類型

MIME(Multipurpose Internet Mail Extensions):多用途網際網路郵件擴充類型,它設計的最初目的是為了在發送電子郵件時附加多媒體資料,讓郵件客戶程式能根據其類型進行處理。然而當它被 HTTP 協定支援之後,它的意義就更為顯著了。

MIME 類型在 HTTP 協定中,用來表示文檔、檔案或位元組流的性質和格式,具體包括了文本、圖像、音頻、視訊以及其他應用程式專用的資料。

浏覽器通常使用 MIME 類型(而不是檔案擴充名)來确定如何處理 URL,是以 Web 伺服器在響應頭中添加正确的 MIME 類型非常重要。如果配置不正确,浏覽器可能會曲解檔案内容,網站将無法正常工作,并且下載下傳的檔案也會被錯誤處理。

MIME 類型通用格式為:type/subtype 由類型(type)與子類型(subtype)兩個字元串中間用 “/” 分隔而組成(不允許空格存在)。

type 表示可以被分多個子類的獨立類别,subtype 表示每個列别細分後的每個類型。

MIME 類型對大小寫不敏感,但是傳統寫法都是小寫。

type 分為兩類:

  • 可以将内容具化的單一類型,如下表所示:
類型 描述 典型示例
text 表明檔案是普通文本,理論上是人類可讀 text/plain, text/html, text/css, text/javascript
image 表明是某種圖像。不包括視訊,但是動态圖(比如動态 gif)也使用 image 類型 image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon, image/vnd.microsoft.icon
audio 表明是某種音頻檔案 audio/midi, audio/mpeg, audio/webm
video 表明是某種視訊檔案 video/webm, video/ogg
application 表明是某種二進制資料 application/octet-stream, application/xml, application/pdf, application/json
  • 可以結合多種單一類型的符合類型 multipart/form-data

我們下面先了解幾何常用的 MIME 類型:

  • text/plain:普通文本格式,通常文本可以使用該類型,如果某些具體擴充名的檔案可以使用相應的 MIME 類型,例如 text/css 等
  • image/jpeg:jpeg\jpg 格式的圖檔
  • application/octet-stream:辨別内容是一個未知的應用程式檔案的位元組流,所有檔案的位元組流都可以使用該類型
  • application/json:辨別内容是 JSON 位元組流

HTTP Header:Content-Type

Content-Type 用來辨別内容的類型,其值為 MIME 類型。常見的兩個例如如下:

  • 我們經常在 Postman 等工具中使用 POST 請求發送 JSON 資料時的請求頭資訊,如下所示:
SpringBoot 檔案上傳和下載下傳(一)
  • 在 HTML 頁面中使用 POST 請求發送 mutipart/form-data 類型的請求時,如下所示:
<form action="/" method="post" enctype="multipart/form-data">
  <input type="text" name="description" value="some text">
  <input type="file" name="myFile">
  <button type="submit">Submit</button>
</form>           

請求頭看起來像這樣(在這裡省略了一些 headers):

POST /foo HTTP/1.1
Content-Length: 68137
Content-Type: multipart/form-data; boundary=---------------------------974767299852498929531610575

---------------------------974767299852498929531610575
Content-Disposition: form-data; name="description"

some text
---------------------------974767299852498929531610575
Content-Disposition: form-data; name="myFile"; filename="foo.txt"
Content-Type: text/plain

(content of the uploaded file foo.txt)
---------------------------974767299852498929531610575
           

HTTP Header:Content-Disposition

Content-Disposition 有兩種使用的場景:

  • 在 multipart/form-data 類型的請求中,Content-Disposition 值隻有 form-data,并且會設定指令 name 用于記錄表單字段名稱,如果有檔案,還會有指令 filename 記錄檔案名稱,如下所示:
Content-Disposition: form-data; name="fieldName"
Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"           
  • 在其他正常請求中,Content-Disposition 值用于訓示回複的内容該以何種形式展示,其值有兩個:① inline:預設值,表示回複中的消息體會以頁面的一部分或者整個頁面的形式展示,但是隻會在文本、圖檔等檔案生效,其他檔案會直接下載下傳;② attachment:意味着消息體應該被下載下傳到本地;大多數浏覽器會呈現一個“儲存為”的對話框,将 filename 的值預填為下載下傳後的檔案名,假如它存在的話。
Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"           

檔案上傳和下載下傳内容見下一篇文章,如果文章對大家有所幫助,歡迎點贊、關注、評論。

SpringBoot 檔案上傳和下載下傳(一)