紧接着上一次的博客,这次来实现一下文件(主要是图片)的上传和下载功能,上一次的博客如下所示:
Springboot集成JWT token实现权限验证-CSDN博客
其实文件的上传和下载功能(后端的部分),在我之前的博客就已经有写了,所以这一次我们更加关注前端部分,还有要知道前后端在这个模块是怎么交互的,之前的博客如下所示:
springboot项目学习-瑞吉外卖(4)-CSDN博客
话不多说,上代码!
1.文件处理类-FileController
package com.kuang.controller;
import com.kuang.common.Result;
import jakarta.servlet.ServletOutputStream;
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.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.UUID;
//上传
@RestController
@RequestMapping("/file")
public class FileController {
//将配置文件中的存储路径赋值给filePath
@Value("${picture.path}")
private String filePath;
//获取"localhost"
@Value("${ip}")
private String ip;
//获取"8082"
@Value("${server.port}")
private String port;
@PostMapping("/upload")
public Result upload(MultipartFile file) throws IOException {
//获取文件原始名称
String originalFilename = file.getOriginalFilename();
//获取文件后缀(含这个".")
String suffixFileName = originalFilename.substring(originalFilename.lastIndexOf("."));
//使用UUID重新给文件命名,为了防止重名
String currentFileName = UUID.randomUUID().toString() + suffixFileName;
//创建一个文件目录对象
File dir = new File(filePath);
//如果这个路径不存在,就创建一个
if (!dir.exists()){
dir.mkdir();
}
//将file指向的文件移动到由basePath+fileName指定的新路径
file.transferTo(new File(filePath + currentFileName));
//返回文件链接,这个链接就是文件的下载地址,这个下载地址是后台提供的
String url = "http://localhost:8082/file/download/" + currentFileName;
System.out.println(url);
return Result.success(url);
}
//下载
@GetMapping("/download/{fileName}")
public void download(@PathVariable String fileName, HttpServletResponse response) throws IOException {
try {
//输入流(读取文件内容)
FileInputStream fileInputStream = new FileInputStream(new File(filePath + fileName));
//输出流(将文件写回浏览器,在浏览器展示图片)
//这里不new一个输出流,而是用response来get一个输出流,因为要返回给浏览器
ServletOutputStream outputStream = response.getOutputStream();
//设置响应类型(类型为图片)
response.setContentType("image/jpg");
//通过输入流来读取文件
byte[] bytes = new byte[1024];
int length = 0;
//如果length不为-1表示还没有读完,则一边读一边写
while((length = fileInputStream.read(bytes)) != -1) {
//向浏览器写文件内容,从0开始写到length为止
outputStream.write(bytes,0,length);
}
//关闭资源
fileInputStream.close();
outputStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
2.前端图片上传样式
<div style="margin-left: 80px;margin-bottom: 20px">
<el-upload
class="avatar-uploader"
action="http://localhost:8082/file/upload"
:headers="{token:user.token}"
:show-file-list="false"
:on-success="handleAvatarSuccess">
<img v-if="user.avatar" :src="user.avatar" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
下面来简单介绍下程序:
上面的user,是从localStorage中获取的,如下:
响应事件程序如下:
methods:{
handleAvatarSuccess(response,file,fileList){
console.log(response)
this.user.avatar = response.data;
},
官方明确表示,这个函数的参数默认有三个,response表示文件上传之后,后端响应给前端的数据,file表示上传的文件对象,fileList是一个数组,表示所有已经上传的文件对象