SpringBoot+Vue2实现图片的上传和回显

SpringBoot+Vue2实现图片的上传和回显

1、环境准备:

  1. 搭建好的SpringBoot项目,需要引入Hutool包。
  2. 搭建好的Vue2项目,在本次实验中将结合ElementUI来实现前端图片的上传和回显功能。

2、引入ElementUI组件

  • <template>
      <div>
        <el-upload
          class="avatar-uploader"
          action="https://jsonplaceholder.typicode.com/posts/"
          :show-file-list="false"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload">
          <img v-if="imageUrl" :src="imageUrl" class="avatar">
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
      </div>
    </template>
    
    <script>
    export default {
      name: "Upload",
      data() {
        return {
          imageUrl: '',
        };
      },
      methods: {
        handleAvatarSuccess(res, file) {
          this.imageUrl = URL.createObjectURL(file.raw);
        },
        beforeAvatarUpload(file) {
          const isJPG = file.type === 'image/jpeg';
          const isLt2M = file.size / 1024 / 1024 < 6;
    
          if (!isJPG) {
            this.$message.error('上传头像图片只能是 JPG 格式!');
          }
          if (!isLt2M) {
            this.$message.error('上传头像图片大小不能超过 6MB!');
          }
          return isJPG && isLt2M;
        }
      }
    }
    </script>
    
    <style scoped>
    .avatar-uploader .el-upload {
      border: 1px dashed #d9d9d9;
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
    }
    .avatar-uploader .el-upload:hover {
      border-color: #409EFF;
    }
    .avatar-uploader-icon {
      font-size: 28px;
      color: #8c939d;
      width: 178px;
      height: 178px;
      line-height: 178px;
      text-align: center;
      background-color: aqua;
    }
    .avatar {
      width: 178px;
      height: 178px;
      display: block;
    }
    </style>
    
  • 主要属性解释:

    1. <el-upload
            class="avatar-uploader"
            action="https://jsonplaceholder.typicode.com/posts/"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload">
            <img v-if="imageUrl" :src="imageUrl" class="avatar">
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
      </el-upload>
      
      • action="https://jsonplaceholder.typicode.com/posts/"
        

        ​ action是文件上传的后端接口,我们在前端上传图片之后,需要将文件保存在指定的路径。

      • :show-file-list="false"
        

        ​ 是否显示已上传的文件列表

      • :before-upload="beforeAvatarUpload"
        

        ​ 是指在图像上传前的校验规则,需要对上传的文件进行一些校验,比如:上传图片时判断是否是图片,文件大小是否超过6MB等,若返回 false 或者返回 Promise 且被 reject,则停止上传。对应的校验规则如下所示(仅供参考):

        beforeAvatarUpload(file) {
        	const isJPG = file.type === 'image/jpeg';
            const isLt2M = file.size / 1024 / 1024 < 6;
        	if (!isJPG) {
        		this.$message.error('上传头像图片只能是 JPG 格式!');
        	}
        	if (!isLt2M) {
        		this.$message.error('上传头像图片大小不能超过 6MB!');
        	}
        	return isJPG && isLt2M;
        }
        
      • :on-success="handleAvatarSuccess"
        

        ​ 上传成功之后的响应事件,比如可以进行文件回显等。此处进行文件回显的方法如下:

        handleAvatarSuccess(res, file) {
        	this.imageUrl = URL.createObjectURL(file.raw);
        },
        
      • 其他属性请参考官方网站:https://element.eleme.cn/#/zh-CN/component/upload

    2. <img v-if="imageUrl" :src="imageUrl" class="avatar">
      

      ​ 图片回显,在此处可能出现的问题就是出现(即:文件上传之后不会回显图片,解决方法见下文):

      Not allowed to load local resource:file:///D:/files/1716169296.jpg

      image-20240520092640490image-20240520092738850

3、后端代码的编写

3.1文件上传:

  • // 文件上传路径
    private String ROOT_PATH = "D:\files";
    /**
         * 文件上传
         * @param file
         * @return
         * @throws IOException
         */
    @PostMapping("/upload")
    public String upload(MultipartFile file) throws IOException {
    	// 获取文件的原始名称:aaa.jpg
    	String originalFilename = file.getOriginalFilename();
    	// 获取文件名:aaa	此处的FileUtil是Hutool包提供的
    	String mainName = FileUtil.mainName(originalFilename);
    	// 获取文件的后缀:jpg
    	String extName = FileUtil.extName(originalFilename);
        // 判断文件上传的路径是否存在,不存在就需要主动创建一个
    	if (!FileUtil.exist(ROOT_PATH)) {
    		// 如果文件的父级目录不存在,则创建一个文件夹
    		FileUtil.mkdir(ROOT_PATH);
    	}
        // 对上传的文件进行重命名,命名规则:当前时间戳.文件后缀
        originalFilename = System.currentTimeMillis() + "." + extName;
        // 创建一个File对象,将上传的文件保存到指定文件上传地址		其中:File.separator表示 \
    	File saveFile = new File(ROOT_PATH + File.separator + originalFilename);
    	// 将文件保存到本地磁盘中:D:\files\1716169296.jpg
    	file.transferTo(saveFile);
    	// 文件上传成功之后需要返回一个文件的链接,这个链接就是文件的下载地址,是后台提供的
    	String url = "http://localhost:8080/file/download/" + originalFilename;
    	return url;
    }
    

3.2、文件下载:

  • /**
    * 文件下载:
    	此处需要将我们之前上传保存的文件加入到客户端(浏览器)中,才能进行文件的正常回显,否则就会出现上述报错。
    * @param fileName
    * @param response
    * @throws IOException
    */
    @AuthAccess
    @GetMapping("/download/{fileName}")
    public void download(@PathVariable String fileName, HttpServletResponse response) throws IOException {
        // 根据前端传回的文件名进行拼接本地文件的路径:D:\files\1716169296.jpg
    	String filePath = ROOT_PATH + File.separator + fileName;
        // 如果文件不存在就直接返回,即文件无法回显。
    	if (!FileUtil.exist(filePath)) {
    		return;
    	}
        // 读取图片的字节信息,保存到字节数组中
    	byte[] bytes = FileUtil.readBytes(filePath);
        // 获取响应对象的输出流对象,需要将字节数组信息写回浏览器中
    	ServletOutputStream outputStream = response.getOutputStream();
        // 将图片的字节数组信息写入到响应对象之中,实现文件的下载
    	outputStream.write(bytes);
        // 刷新输出流对象
    	outputStream.flush();
        // 关闭资源
    	outputStream.close();
    }
    

4、修改前端代码:

  • 图片上传路径修改(此处对应的是后端接口中的文件上传接口):

    action="http://localhost:8080/file/upload"
    
  • 图片回显路径修改(此处对应的是后端接口中的文件下载接口):

    handleAvatarSuccess(res, file) {
        // 根据文件上传接口传回的数据是一个文件下载的链接:http://localhost:8080/file/download/1716169296.jpg,所以在此处只需要接收到这个参数即可,如果是返回一个上传后的文件名,则需要去拼接Url路径即可
    	this.imageUrl = res
    },
    

5、为什么无法通过本地路径直接回显图片:

  • 原因:在前后端分离项目中,浏览器会出于安全考虑,不允许用户通过网页去访问本地的文件。
  • 解决方法之一:通过读取本地的文件,将文件保存到浏览器中,既可以正常进行图片的回显。
  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值