SpringBoot+Vue图片上传实现总结

一、项目介绍

后端:springboot
前段: vue+element-ui组件

杂谈

图片上传在最近的项目中经常遇见,而且每次的需求也不一样。每次都能遇到新的坑,打算记录一下,写个demo方便下次使用。

二、测试

1. 图片上传组件

element UI 官方网站
图片上传组件(来自官网):

<el-upload
	action=""
	list-type="picture-card"
	:http-request="requestUpload"
	:on-preview="handlePictureCardPreview"
	:on-remove="handleRemove"
	:on-change="handleChange"
	:before-upload="beforeUpload"
	:file-list="fileList"
	:limit="4"
	:on-exceed="exceedTips"
	:multiple="true"
>
  <i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
  <img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
<script>
  export default {
    data() {
      return {
        dialogImageUrl: '',
        dialogVisible: false
      };
    },
    methods: {
      handleRemove(file, fileList) {
        console.log(file, fileList);
      },
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      }
    }
  }
</script>

2. 常用钩子说明

来自官网!
在这里插入图片描述

3. 实战

3.1 需求

用户输入用户名和密码,并且上传多张个人图片。(瞎说)
要求:
用户信息和图片同时上传。

3.2 解决思路

构造form表单数据,将用户名,密码和图片同时发送。
代码:

<el-form ref="form" :model="form" label-width="80px" >
        <el-form-item label="用户名">
          <el-input v-model="form.name" ></el-input>
        </el-form-item>
        <el-form-item label="密码">
          <el-input v-model="form.password" ></el-input>
        </el-form-item>
        <el-form-item label="头像">
            <el-upload
              action=""
              list-type="picture-card"
              :http-request="requestUpload"
              :on-preview="handlePictureCardPreview"
              :on-remove="handleRemove"
              :on-change="handleChange"
              :before-upload="beforeUpload"
              :file-list="fileList"
              :limit="4"
              :on-exceed="exceedTips"
              :multiple="true"
            >
              <i class="el-icon-plus"></i>
            </el-upload>
            <el-dialog :visible.sync="dialogVisible">
              <img width="100%" :src="dialogImageUrl" alt="">
            </el-dialog>

        </el-form-item>


        <el-form-item>
          <el-button type="primary" @click="onSubmit">提交</el-button>
          <el-button>取消</el-button>
        </el-form-item>
      </el-form>

不用原生的action上传文件,我们需要自定义上传。
那何时触发上传图片操作呢?
点击提交,一起发送。

3.3 :file-list="fileList"说明

在这里插入图片描述
我这里的fileList相当于全局变量。
打印出来看看:
在这里插入图片描述

3.4 on-change 和 before-upload 钩子说明

在这里插入图片描述
on-change和before-upload 钩子经常会作为上传文件限制方式,例子:

      handleChange(file,fileList){
        console.log("handleChange执行");
        console.log(file)
        this.fileList = fileList;
      },
      // 上传预处理,不含fileList参数
      beforeUpload(file) {
        console.log("beforeUpload执行");
        console.log(file)
        //判断文件是否上传重复
        let existFile = this.fileList.slice(0, this.fileList.length - 1).find(f => f.name === file.name);
        //上传文件是不是图片
        let fileImg = file.type.indexOf("image/") === -1;
        if (existFile || fileImg) {
          this.msgError("文件格式错误或文件重复,请上传图片类型,如:JPG,PNG后缀的文件。");
          //不匹配就pop
          this.fileList.pop();

        }
      },

测试:
在这里插入图片描述

  1. 两者执行顺序:
    在这里插入图片描述
    根据控制台输出我们可以看到是on-change比before-upload先执行。并且on-change钩子含有fileList参数。当我们想要在我们增添图片或者删除待上传图片实时更新全局fileList,那我们就需要设置on-change钩子并且添加语句:this.fileList = fileList;
    我习惯在before-upload钩子中进行文件筛选,最为最后一步关卡。
  2. 两者参数说明
    on-change钩子 ==》function(file, fileList)方法中的file对象

    before-uploa钩子 ==》function(file)方法中的file对象其实是不一致的

在这里插入图片描述
而我们后台需要接受的其实是,后面那个file,也就是on-change 钩子中file对象的raw属性!!!
这点对于小白来说,经常会误用,导致后台接收不到文件!

3.5 构建form表单数据

文件数据以及准备好了fileList,用户数据也是存在的。那如何将文件数据和用户数据一起发送给后端呢?

答案就是,构建FormData对象!
例子:

      onSubmit() {
        var formData = new FormData;
        formData.append("username",this.form.name);
        formData.append("password",this.form.password);
        this.fileList.forEach(function (file) {
        	//fileList里的file对象就是on-change钩子中的对象。后台是接收不到的
        	//能接收的是file.raw对象
            formData.append("file",file.raw);
        })
        axios.post("",formData).then(res=>{
          console.log(res);
        })
      },

后台测试

    @PostMapping("/test")
    public AjaxResult test(String username,String password,MultipartFile[] file) throws IOException {
        System.out.println("用户名"+username);
        System.out.println("密码"+password);
        System.out.println("文件个数"+file.length);
        for (int i = 0; i < file.length; i++) {
            File tempFile = new File("D:/"+i+""+".jpg");
            file[i].transferTo(tempFile);
        }
        return AjaxResult.success();
    }

输出:
在这里插入图片描述在这里插入图片描述在这里插入图片描述

测试成功了!

4. 常见问题

后台接收的文件格式

在这里插入图片描述

请求类型

模拟的是表单数据
在这里插入图片描述
spring是不能用@RequestBody注解的接收含有文件数据的!!!

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值