一.简介

文件上传涉及到两个部分,一个是前端程序,另一个是服务端程序。
二.前端程序
1.前端上传文件必须有三要素:
1.form表单,并且在form表单中要定义一个表单项,类型为file。其效果是会弹出一个"选择文件"的按钮,点击按钮就会弹出窗口用来上传文件。效果如下:


2.表单的提交方式必须是post方式,因为我们要上传的文件可能比较大,因此要使用post提交方式。
3.在form表单中指定文件的编码格式为"multipart/form-data",即enctype="multipart/form-data"。 因为普通默认的编码格式是不适合传输大型的二进制数据的。

2.我们需要将前端文件放在resources目录下的static文件夹中:

代码如下:
XML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
姓名: <input type="text" name="username"><br>
年龄: <input type="text" name="age"><br>
头像: <input type="file" name="image"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
action指定表单往哪里提交,method指定表单的提交方式为post,enctype指定表单的编码格式为"multipart/form-data"

如果要进行文件上传,不仅要设置enctype为multipart/form-data,而且必须在form表单项中设置type="file"。
运行该前端文件,在浏览器中打开,点击提交,选择中国梦.txt文件

在提交之前先通过F12打开开发者工具来抓取网络请求。
点击提交,在提交页面中显示404,这是正常的,因为服务端程序还没开发。
我们找到POST请求,打开原始并找到请求头,其中有一个Content-Type:即是文件的编码格式,我们这里先暂时没有设置,因此是默认的application/x-www-form-urlencoded格式。
我们来具体看使用默认的表单编码格式数据是以什么样的格式提交的。

点击请求,并打开原始开关,就显示出来以默认方式提交表单后数据的编码格式。我们看到的被标记的部分是"中国梦"这三个字的url编码。因此我们可以得出结论:
如果以默认方式进行提交,那么提交的就是该文件的文件名!
3.如果设置enctype为multipart/form-data,再次提交:
我们会发现Content-Type属性为multipart/form-data,boundary为不同表单项之间的分隔符

展示的内容被分为了三个部分,由boundary进行分隔
注意:然后上传的是图片或者音视频,是看不到的会是乱码,因为是2进制文件。
三.后端(服务端)程序

我们设置Controller层来对前端传输过来的数据进行接收,对于普通的表单项,使用正常的参数变量进行接收即可,对于图片、文本、音视频等二进制类型的文件来说,使用一个特定的变量类型MultipartFile进行文件接收即可。要想成功接收到传输过来表单项,必须要保证表单项的名称和方法形参的名称要保持一致。如果不一致,要使用注解@RequestParam,@RequestParam当中指定的value属性就是前端所传递的参数名。
1.controller层
java
package com.gjw.controller;
import com.gjw.pojo.Result;
import com.gjw.util.AliOSSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
@Slf4j
public class UploadController {
@PostMapping("/upload")
public Result upload(String username, Integer age, MultipartFile file) {
log.info("文件上传:{},{},{},{}", username, age, file);
return Rusult.success();
}
}
直接使用浏览器访问localhost:8080/upload.html访问该表单。 输入姓名为Tom,年龄为18,头像选择"中国梦.txt"文件
点击提交后,程序运行到断点,文件已经提交上去了,但是提交到哪里了呢?找到location,里面的路径就是文件的所在目录。

