SpringBoot 文件上传和下载(一)

在现在微服务系统中,文件的上传和下载可以说是常规操作,这篇文章带领大家一起探究一下 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 数据时的请求头信息,如下所示:
  • 在 HTML 页面中使用 POST 请求发送 mutipart/form-data 类型的请求时,如下所示:

请求头看起来像这样(在这里省略了一些 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 文件上传和下载(二)