【FileVO】
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class FileVO {
private String virtualPath; //前台访问的逻辑路径
private String fileName; ???//文件名称
}
【FileController】
@RestController
@CrossOrigin
public class FileController {
@PostMapping("/upload")
public FileVO upload(MultipartFile file) throws IOException {
FileVO fileVO = UploadUtils.upload(file);
return fileVO;
}
@GetMapping("/download")
public void downloadFile(HttpServletResponse response, String filePath) throws IOException {
// 清空输出流
response.reset();
response.setContentType("application/x-download;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="+ new String(filePath.getBytes("utf-8"), "utf-8"));
UploadUtils.download(response.getOutputStream(),filePath);
}
}
【文件上传下载工具类】
public class UploadUtils {
private static String localPathDir = "d:/files";
public static FileVO upload(MultipartFile file) throws IOException {
//获取文件名称
String fileName = file.getOriginalFilename();
//实现分目录存储
String datePath =
new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
//最终本地图片存储路径
String localDir = localPathDir + datePath;
//需要创建目录
File dirFile = new File(localDir);
if(!dirFile.exists()){
dirFile.mkdirs();
}
//采用UUID防止文件重名
String uuid = UUID.randomUUID().toString()
.replace("-", "");
//获取文件类型
String fileType =
fileName.substring(fileName.lastIndexOf("."));
//重新拼接文件名
String realFileName = uuid + fileType;
//最终文件存储的路径+文件名 = d:/files/2021/11/11/uuid.xls
String filePathAll = localDir + realFileName;
//实现文件上传
File realFile = new File(filePathAll);
file.transferTo(realFile);
//封装FileVO对象 ?//2021/11/11/uuid.pdf 图片路径 稍后给前台传递
//我们不可能将filePathAll告诉用户,这样不安全,容易被攻击
String virtualPath = datePath + realFileName;
//将文件存储路径(半个路径,没有具体盘符或根目录) 和 重命名后的文件名 封装到实体类中
return new FileVO(virtualPath,realFileName);
}
public static Object download(OutputStream os, String filePath) throws IOException {
//下载文件的路径
String downPath = localPathDir+filePath;
//读取目标文件
File f = new File(downPath);
//创建输入流
InputStream is = new FileInputStream(f);
//做一些业务判断,我这里简单点直接输出,你也可以封装到实体类返回具体信息
if (is == null) {
System.out.println("文件不存在");
}
//利用IOUtils将输入流的内容 复制到输出流
//org.apache.tomcat.util.http.fileupload.IOUtils
//项目搭建是自动集成了这个类 直接使用即可
IOUtils.copy(is, os);
os.flush();
is.close();
os.close();
return null;
}
}
【Vue前端代码】
$(function(){
var model = {tu:'', url:''};
var vm = new Vue({
el:'#app',
data:model,
methods:{
upload(e){
var file = e.target.files[0];// 文件对象
var formdata = new FormData();// 表单对象
formdata.append('file', file);// 把文件放入表单中
axios.post('/file/upload',formdata,{
header:{'Content-Type':'multipart/form-data'}
}).then((res) => {
alert(res.data);
this.tu = '/image/' + file.name;
this.url = '/image/' + file.name;
});
}
}
});
});