springboot 实现本地文件存储
实现过程
- 上传文件
- 保存文件(本地磁盘)
- 返回文件HTTP访问服务器路径给前端,进行效果展示
存储
- 服务端接收上传的目的是提供文件的访问服务,对于SpringBoot而言,其对静态资源访问提供了很好的支持,使用其提供的基本默认配置可以满足开发需求,同时,又支持开发人员进行自定义配置。
SpringBoot默认将 / 所有访问映射到以下目录:**
- classpath:/META-INF/resources
- classpath:/static
- classpath:/public
- classpath:/resources
SpringBoot默认会挨个从pubic、resources、static里面找是否存在相应的资源,如果有则直接返回。
问题
- 如果都放在classpath目录下打包的文件就会很大
- 代码与文件数据不能分开存储,就意味着文件数据的备份将变得复杂
解决方法
springboot提供了 spring.resources.static-locations
配置自定义静态文件的位置:
注:该配置有问题,在下面以解决
spring:
web:
resources:
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${demo.web.upload-path}
# 设置Http能访问的本地资源路径
demo:
web:
upload-path: D:/MineFile/zuoye/xm/equipment-management-system/qhjdata/
- 配置 demo.web.upload-path 为与项目代码分离的静态资源路径,即:文件上传保存根路径
- 配置 spring.web.resources.static-locations 除了带上SpringBoot默认的静态资源路径之外,加上file:${demo.web.upload-path}指向外部的文件资源上传路径,即:该路径下的静态资源可以直接对外提供HTTP访问服务
/**
* 本地上传
* @param file
* @param request
* @return
*/
@RequestMapping("/file")
public R fileSave(MultipartFile file, HttpServletRequest request) {
if (file == null) {
throw new RRException("参数为空");
}
// 在 uploadPath 文件夹中通过日期对上传的文件归类保存
// 例如:/2022/02/22/df9a66f1-760b-4f95-9faf-b5a216966718.png
String format = sdf.format(new Date());
File folder = new File(uploadPath + format);
if (!folder.isDirectory()) {
folder.mkdirs();
}
// 对上传的文件重命名, 避免文件重名
String oldName = file.getOriginalFilename();
String newName = UUID.randomUUID().toString()
+ oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
// 文件保存
file.transferTo(new File(folder, newName));
// 添加日志输出
logger.info("文件保存成功:" + folder.getPath() + File.separator + newName);
// 返回上传文件的访问路径
// 例如:http://localhost:9999/2022/02/22/df9a66f1-760b-4f95-9faf-b5a216966718.png
String filePath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + request.getContextPath() + "/" + format + newName;
return R.ok().put("filePath", filePath);
} catch (IOException e) {
throw new RRException("系统错误");
}
}
前端
参考:spring boot 整合 minio存储 【使用篇】
返回得到一个地址,即可访问
问题
- 已解决
由于该项目涉及token,访问链接报错
但我看网络里又有token
已解决
通过访问路径解决token问题
<el-upload
class="upload-demo"
ref="upload"
drag
action="#"
:on-change="handleChangeSelect"
:on-exceed="handleExceed"
:file-list="fileList"
:limit="1"
multiple
:auto-upload="false"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div
class="el-upload__tip"
slot="tip"
>只能上传jpg/png文件,且不超过500kb</div>
<div class="el-upload__tip" slot="tip">
访问路径:<a :href="`${filePath}?token=${token}`" target="_blank">点击跳转{{ filePath }}</a>
</div>
</el-upload>
创建token变量获取
this.token = this.$cookie.get('token')
访问路径404问题
修改yml配置文件
修改前
spring:
web:
resources:
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${demo.web.upload-path}
修改后
spring:
resources:
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${demo.web.upload-path}
# 设置Http能访问的本地资源路径
demo:
web:
upload-path: D:/MineFile/zuoye/xm/equipment-management-system/qhjdata/
参考
SpringBoot实现本地文件存储及预览