紧接着上一次的博客,这次来实现一下文件(主要是图片)的上传和下载功能,上一次的博客如下所示:
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-uploadclass="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是一个数组,表示所有已经上传的文件对象