上传功能的思想
上传功能只需要在controller层接收客户端上传的图片,处理上传请求,将图片的路径、大小、类型以及图片的名称等信息返回给客户端,而不会去做写入数据库操作,因为现在很多云平台已经提供了上传文件返回文件信息的接口,直接使用就可以,如果上传图片时将图片存入数据库,不易于后期替换为云平台的版本。因此上传文件之解决上传,而不解决写入数据库,项目有可能以后使用云平台的上传,然后写入数据库我们自己去做。
MultipartFile介绍
MultipartFile 是 Spring 框架提供的一个接口,用于处理 HTTP 请求中的文件上传。它表示一个上传的文件,可以通过该接口获取文件的相关信息和内容。
- 通过 MultipartFile 提供的方法获取文件的相关信息,例如文件名、大小、内容等。常用的方法包括:
- getOriginalFilename():获取上传文件的原始文件名。
- getSize():获取上传文件的大小,以字节为单位。
- getBytes():获取上传文件的内容,返回字节数组。
- transferTo(File dest):将上传的文件保存到指定的目标文件中。
上传的具体实现
上传的方法设计
@PostMapping("/upload/image/article")
@ApiOperationSupport(order = 100)
@ApiOperation("上传文章图片")
public JsonResult uploadArticleImage(@RequestParam("file") MultipartFile multipartFile) throws Throwable {
return JsonResult.ok(uploadResult);
}
对于上传文件的检查
1、不上传文件提交请求不可以,上传0字节文件不可以
if (multipartFile == null || multipartFile.isEmpty()) {
String message = "上传文章图片失败,请选择您要上传的文件!";
log.warn(message);
throw new ServiceException(ServiceCode.ERROR_UPLOAD_EMPTY, message);
}
2、限制上传文件大小
@Value("${tea-store.upload.article-image.max-size}")
private Integer articleImageMaxSize;//5
long size = multipartFile.getSize();
if (size > articleImageMaxSize * 1024 * 1024) {
String message = "上传文章图片失败,不允许使用超过" + articleImageMaxSize + "MB的图片文件!";
log.warn(message);
throw new ServiceException(ServiceCode.ERROR_UPLOAD_EXCEED_MAX_SIZE, message);
}
3、显示上传文件类型(MIME类型)
@Value("${tea-store.upload.article-image.types}")
private List<String> articleImageValidTypes;//image/jpeg, image/png, image/gif
String contentType = multipartFile.getContentType();
if (!articleImageValidTypes.contains(contentType)) {
String message = "上传文章图片失败,请使用以下类型的图片文件:" + articleImageValidTypes;
log.warn(message);
throw new ServiceException(ServiceCode.ERROR_UPLOAD_INVALID_TYPE, message);
}
上传文件的文件目录
绝对路径根基文件路径(C:/Users/Desktop/ )+文件夹名(resources/)+分类名(article-image/)+上传日期最为文件名
文件目录:uploadDir
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/");
@Value("${tea-store.upload.root-dir-name}")
private String uploadRootDirName;//C:/Users/Desktop/
@Value("${tea-store.upload.base-dir-name}")
private String baseDirName;//resources/
private String articleImageDirName = "article-image/";
String dirName = simpleDateFormat.format(new Date());
File uploadBaseDir = new File(uploadRootDirName, baseDirName);
File articleImageDir = new File(uploadBaseDir, articleImageDirName);
File uploadDir = new File(articleImageDir, dirName);
上传文件的文件名
文件名:newFullFileName
String newFileName = UUID.randomUUID().toString();
String originalFilename = multipartFile.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
String newFullFileName = newFileName + suffix;
将上传的文件保存到指定目标文件中
newFile=uploadDir+newFullFileName
File newFile = new File(uploadDir, newFullFileName);
multipartFile.transferTo(newFile);
封装返回上传的文件数据
@Data
public class UploadResult implements Serializable {
//文件URL
private String url;
//文件大小
private long fileSize;
//文档MIME类型
private String contentType;
//文件名
private String fileName;
}
装数据并返回
相对路径的本地ip:服务端口+文件夹名(resources/)+分类名(article-image/)+上传日期最为文件名+文件名
@Value("${tea-store.upload.host}")
private String host;//http://localhost:${server.port}/
String url = new StringBuilder()
.append(host)
.append(baseDirName)
.append(articleImageDirName)
.append(dirName)
.append(newFullFileName)
.toString();
UploadResult uploadResult = new UploadResult();
uploadResult.setUrl(url);
uploadResult.setFileSize(size);
uploadResult.setContentType(contentType);
uploadResult.setFileName(newFullFileName);
return JsonResult.ok(uploadResult);
相关配置
1、相关文件上传配置
# 学茶商城的自定义配置
tea-store:
# 文件上传
upload:
# 对外访问的主机,必须使用 / 作为最后一个字符
host: http://localhost:${server.port}/
# 上传的根级文件夹名称,必须使用 / 作为最后一个字符
root-dir-name: C:/Users/TEACHER/Desktop/
# root-dir-name: /Users/chengheng/Desktop/JSD2023
# 上传的文件夹名称,也会作为访问资源时的URL第1级目录名,必须使用 / 作为最后一个字符
base-dir-name: resources/
# 文章图片
article-image:
# 允许的文件类型,必须配置文件类型的MIME值,多种类型使用英文的逗号分隔
types: image/jpeg, image/png, image/gif
# 最大尺寸,单位:MB
max-size: 5
# 商品图片
goods-image:
# 允许的文件类型,必须配置文件类型的MIME值,多种类型使用英文的逗号分隔
types: image/jpeg, image/png, image/gif
# 最大尺寸,单位:MB
max-size: 5
2、静态资源配置:将上传的文件路径配置为静态资源路径,能够进行访问。上传配置,由于使用springboot框架默认限制1MB,整个项目上传超过1MB就出系统级别的错误,因此需要配置项目中上传文件无论是视频还是图片等文件,都不可以超过配置大小值。
# Spring的配置
spring:
# servlet配置
servlet:
# 上传配置
multipart:
# 最大文件尺寸
max-file-size: 500MB
# 最大请求尺寸
max-request-size: 500MB
# WEB配置
web:
# 静态资源配置
resources:
# 静态资源文件夹,如果多个,使用英文的逗号分隔,本地路径必须使用 file: 作为前缀
static-locations: classpath:static, file:${tea-store.upload.root-dir-name}
图片路径默认未携带JWT,登录成功的用户是访问不了图片,将图片路径放到配置的白名单中,才能进行访问。配置路径:"/resources/**"