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"
文件上传和下载内容见下一篇文章,如果文章对大家有所帮助,欢迎点赞、关注、评论。