文件上传

  • 文件上传:是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或下载的过程
  • 文件上传在项目中应用非常广泛,微博、微信朋友圈都用到了文件上传功能

前端要求:

1
2
3
4
5
<form action="/upload" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="name"> <br>
年龄:<input type="text" name="age"> <br>
图像:<input type="file" name="file"> <br>
</form>

请求方式必须为Post,enctype必须为multipart/form-data,还需要表单项<input type="file>"

后端要求:

1
2
3
4
5
6
7
public class UploadController {
@PostMapping("/upload")
public Result handleFileUpload(String name, Integer age, MultipartFile file) {
log.info("文件上传:{}", file);
return Result.success();
}
}

对于前端上传过来的文件,需要使用MultipartFile接受

当接收到前端发送过来的文件后,会在本地创建临时目录以及对应的临时文件

本地存储

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@PostMapping
public Result upload(String name, Integer age, MultipartFile file) throws IOException {
log.info("接收到的参数:{},{},{}",name,age,file);
// 获取原始文件名
String originalFilename = file.getOriginalFilename();

// 转换原始文件名
String extension = originalFilename.substring(originalFilename.lastIndexOf(".")); // 获取后缀
String newFileName = UUID.randomUUID() + extension; // 利用UUID生成不会重复的文件名称

// 保存文件
file.transferTo(new File("E:\\MyFiles\\" + newFileName));
return Result.success();
}

关键就是调用MultipartFile类下的transferTo方法,方法参数为File对象,File对象需要指定存放文件的路径以及文件名称

MultipartFile类的getOriginalFilename方法可以获取到原始的文件名称,但是如果出现重名的文件,可能会导致数据覆盖

所以为了保证文件名称的唯一性,还需要使用UUID生成唯一值

注意:Spring项目默认单个文件上传大小为1MB总请求最大10MB。不过这个可以通过修改配置文件进行修改:

1
2
3
4
5
6
7
spring:
servlet:
multipart:
# 最大单个文件大小
max-file-size: 10MB
# 最大请求大小
max-request-size: 100MB

OSS

如果将文件直接保存在本地服务器中,前端无法直接访问被保存的资源,并且会减少大量的服务器硬盘容量

可以通过FastDFS和MinIO搭建专门的文件存储服务器(大型项目或大型企业),或者直接使用第三方提供的文件存储服务器

阿里云OSS

阿里云对象存储OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。使用OSS,就可以直接通过网络随时存储或调用包括文本、图片、音频和视频等在内的各种文件

使用教程访问:09-后端Web实战(员工管理) - 飞书云文档

教程里配置完Access Key后,最好将IDEA重启一下

参数配置化

Value注解

  • 值将一些需要灵活变化的参数,配置在配置文件中,然后通过@Value注解来注入外部配置的属性
1
2
3
4
5
aliyun:
oss:
endpoint: https://oss-cn-shanghai.aliyuncs.com
bucketName: norlcyan-javaweb-ai
region: cn-shanghai
1
2
3
4
5
6
7
8
9
10
11
@Component
public class AliyunOSSOperator {
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.bucketName}")
private String bucketName = "norlcyan-javaweb-ai";
@Value("${aliyun.oss.region}")
private String region = "cn-shanghai";

...
}

ConfigurationProperties注解

Value只能一个一个的对成员属性进行配置赋值,而ConfigurationProperties注解则可以批量对成员属性进行注解,前提是配置文件中的属性名要和类中的属性名匹配

Snipaste_2025-08-12_23-27-19

注意:

  1. ConfigurationProperties注解是放在类上的,而Value注解是放在成员属性上
  2. 图片中的案例是把AliyunOSSOperator工具类中的成员属性单独抽取成一个实体类,工具类中需要用到哪个属性时,就通过get方法获取

@Value和@ConfigurationProperties

  1. 成员属性较少,还是@Value更加方便,因为不需要考虑属性名称匹配的问题

  2. 成员属性较多,考虑复用,建议使用@ConfigurationProperties