springboot+vue前后端分离项目-项目搭建6-文件上传下载
1. 新增com/example/demo/controller/FileController.java
package com.example.demo.controller;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.example.demo.common.Result;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
@RestController
@RequestMapping("/files")
public class FileController {
@Value("${server.port}")
private String port;
private static final String ip = "http://localhost";
/**
* 上传接口
* @param file
* @return
* @throws IOException
*/
@PostMapping ("/upload")
public Result<?> upload(MultipartFile file) throws IOException {
String originalFilename = file.getOriginalFilename(); //获取文件的名称
String flag = IdUtil.fastSimpleUUID(); //定义文件的唯一标识(前缀),防止重复文件覆盖
String rootFilePath = System.getProperty("user.dir") + "/springbootdemo/src/main/resources/files/" + flag + "_" + originalFilename;//获取上传的路径
FileUtil.writeBytes(file.getBytes(),rootFilePath); //文件写入上传的路径
return Result.success(ip + ":" + port + "/files/" + flag); //返回结果
}
/**
* 下载接口
* @param flag
* @param response
*/
@GetMapping("/{flag}")
public void getFiles(@PathVariable String flag, HttpServletResponse response){
OutputStream os; //新建一个输出流对象
String basePath = System.getProperty("user.dir") + "/springbootdemo/src/main/resources/files/";//定义文件路径
List<String> fileNames = FileUtil.listFileNames(basePath); //获取所有文件名称
String fileName = fileNames.stream().filter(name -> name.contains(flag)).findAny().orElse("");//找到与flag匹配的文件
try {
if(StrUtil.isNotEmpty(fileName)){
response.addHeader("Content-Dispositon", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.setContentType("application/octet-stream");
byte[] bytes = FileUtil.readBytes(basePath + fileName);//通过文件路径读取文件字节流
os = response.getOutputStream();//通过输出流返回文件
os.write(bytes);
os.flush();
os.close();
}
} catch (Exception e) {
System.out.println("文件下载失败");
}
}
}
使用Postman测试效果,官网下载地址:https://www.postman.com/
上传文件
后台:
下载文件:选择 Send and Download,下载后返回流,自己重命名保存
2.vue/src/views/Book.vue里增加文件上传,测试,报错
Access-Control-Allow-Origin出现跨域问题
解决:com/example/demo/common下新增CorsConfig.java配置类,CorsFilter记得导入springframework.web下的
package com.example.demo.common; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { //当前跨域请求最大有效时长,默认1天 private static final long MAX_AGE = 24 * 60 * 60; @Bean public CorsFilter corsFilter(){ CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*");// 1 设置访问源地址 corsConfiguration.addAllowedHeader("*");// 2 设置访问源请求头 corsConfiguration.addAllowedMethod("*");// 3 设置访问源请求方法 corsConfiguration.setMaxAge(MAX_AGE); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", corsConfiguration); CorsFilter corsFilter = new CorsFilter(source); return corsFilter; } }
3.数据库book表增加cover字段,entity同步增加,优化Book.vue
效果:
4.进一步优化Book.vue,现在上传之后浏览器会记录上传的文件,再打开新增,会把刚刚上传的文件再次带入,修改如下,进入dialog之前清除历史文件,但是第一次点击会报错,因为dialog还没显示过,找不到ref="update",所以使用$this.nextTick,就可以找到后加载出来的dialog
以上仅供参考,如有疑问,留言联系
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!