深度解析源码之SpringMVC文件上传为什么要用POST请求还要设置请求头

文章详细探讨了SpringMVC中处理文件上传的机制,特别是为何使用POST请求和设置Content-Type为multipart/form-data。通过检查MultipartResolver和CommonsMultipartResolver的实现,解释了Spring如何判断和解析文件上传请求,并遵循RFC1867协议标准。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

深度解析源码之SpringMVC文件上传为什么要用POST请求还要设置请求头

从本篇文章开始,来逐步介绍里面每一步的细节处理流程。
首先看到doDispatch方法的第一个重要操作就是校验文件上传请求。代码如下:
在这里插入图片描述
这个方法是如何校验文件上传请求的呢? 在看这个方法之前,我们先来回忆回忆,之前在写文件上传前端代码的时候,有两个约定俗成的原则:

  • 请求方式要是POST类型的
  • 要设置enctype属性为"multipart/form-data"类型

我们带着这两个约定的原则来看看SpringMVC中是如何来判断文件上传请求的,打开checkMultipart方法的代码,核心代码如下:
在这里插入图片描述
在上面代码第2行这有个判断,调用了multipartResolver的isMultipart方法,这个对象我们在之前介绍Spring九大组件时提到过,它是SpringMVC九大组件中的其中一个,在SpringMVC九大组件初始化的时候,会从容器中去获取这个组件,如下:
在这里插入图片描述
如果我们在Spring容器中没有装配这个类型的Bean,那么应用就没办法支持SpringMVC的文件上传。 我们继续看上面的multipartResolver的isMultipart是干嘛用的呢?

先来看看官方的解释:
在这里插入图片描述
这个方法就是来看看request请求中的content-type是否为"multipart/form-data"类型的。也就是我们在form表单中设置的enctype属性。下面来看看这个方法的实现。

MultipartResolver本身是SpringMVC提供的一个文件上传的标准化接口,我们可以基于这个接口来实现自己的文件上传逻辑,但是在SpringMVC中,对这个接口提供了一个默认的实现,在spring-web这个模块中,对应的实现类的类名是CommonsMultipartResolver,我们来看看这个实现类里面的逻辑:

在这里插入图片描述

里面直接调用了commons-fileupload组件的isMultipartContent方法,这个方法是apache提供的一个文件上传组件,对应的实现如下:

在这里插入图片描述
我们看到,在66行,第一个判断逻辑是判断是否为POST请求,所以验证了之前我们提到的文件上传第一个原则,要是POST类型的请求。

如果是POST请求,将会再去调用isMultipartContent方法,校验HTTP请求头信息中的Context-Type属性,如下:

在这里插入图片描述
在这里插入图片描述
我们看到上面的if判断中,只是校验了Content-Type是否是"multipart/“开头的,但是并不是一定要是"multipart/form-data”,那就只有一种可能,就是还有其他类型的Content-Type可以支持文件上传了。

那么判断它是文件上传请求之后呢?

那当然是要解析文件上传请求了,也就是下面代码中的红框部分了
在这里插入图片描述
这个方法里面就是将普通的HttpServletRequest中的文件信息进行解析,然后封装为MultipartHttpServletRequest对象,代码如下:

在这里插入图片描述
默认不会走延迟解析这种方式,直接解析request请求,在这个parseRequest方法中就是一系列commons-fileupload组件的操作了,如下:

在这里插入图片描述
这个parseRequest方法再往里,就是从请求中读取文件输入流,然后封装到MultipartParsingResult中,最后再把MultipartParsingResult包装为一个文件请求对象返回。commons-fileupload中的操作,有兴趣可以留言我们再展开聊。

这一切准备就绪之后,就回到我们最开始的doDispatch方法中了,如下
在这里插入图片描述

如果返回的请求和原始请求不一样,就表示解析到了文件,再下面的步骤就会进行文件的写文件操作。

对于文件请求的判断我们就介绍到这,可以自己结合代码捋一捋。文章结尾我们再来聊一个问题:

文件上传为什么一定得是POST请求方式,Content-Type为什么一定得是"multipart/form-data"等方式?

请求用GET还是POST,就得看他们有什么区别,我们都知道,最大的一个区别就是GET请求能传输的数据一次性最多只能到1024字节,而POST请求则没有限制,所以一般传文件,请求数据肯定都相对比较大,就得用POST请求。

为什么Context-Type这个请求头就一定得是"multipart/form-data",这个没有为什么,就是"RFC1867"协议中定义的一个文件上传标准。也就是"互联网工程任务组"定义的一些标准属性,属于一些底层协议层面的标准,那么你上层应用想要用这种功能,就必须要遵守人家定义的这个标准。

码字实属不易,如果有收获,请动动手指,点个赞和关注鼓励一下呗!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FBI HackerHarry浩

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值