基于SpringBoot + Vue实现单个文件上传(带上Token和其它表单信息)的前后端完整过程

梦想不抛弃苦心追求的人,只要不停止追求,你们会沐浴在梦想的光辉之中。再美好的梦想与目标,再完美的计划和方案,如果不能尽快在行动中落实,最终只能是纸上谈兵,空想一番。只要瞄准了大方向,坚持不懈地做下去,才能够扫除挡在梦想前面的障碍,实现美好的人生蓝图。基于SpringBoot + Vue实现单个文件上传(带上Token和其它表单信息)的前后端完整过程,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

有时遇到这种需求,在上传文件的同时还需要带上token凭据和其它表单信息,那么这个需求前端可以使用FormData数据类型来实现。FormData和JSON一样也是通过body传递的,前者支持字符串和二进制文件,后者只能是字符串,如下图1,图2所示。

基于SpringBoot + Vue实现单个文件上传(带上Token和其它表单信息)的前后端完整过程

图一

基于SpringBoot + Vue实现单个文件上传(带上Token和其它表单信息)的前后端完整过程

  图二

一、后端代码

(1)控制层(GameController.java)

@PostMapping(value = "uploadSingleFile")
@ResponseBody
public CommonResponse uploadSingleFile(@RequestHeader("Authorization") String token,
                                       @RequestParam("file") MultipartFile file,
                                       @RequestParam("username") String username) {
    return gameService.uploadSingleFile(token, file, username);
}

(2)接口层(IGameService.java)

CommonResponse uploadSingleFile(String token, MultipartFile file, String username);

(3)实现层(GameServiceImpl.java)

@Value("${system.upload-file-path}")
private String UploadFilePath;

@Override
public CommonResponse uploadSingleFile(String token, MultipartFile file, String username) {
    System.out.println(token);
    System.out.println(username);
    try {
        String uuidStr = UUID.randomUUID().toString();
        String uuid = uuidStr.substring(0, 8) + uuidStr.substring(9, 13) + uuidStr.substring(14, 18) + uuidStr.substring(19, 23) + uuidStr.substring(24);

        String originFileName = file.getOriginalFilename(); // 原文件名,如:HelloWorld.xlsx
        int beginIndex = originFileName.lastIndexOf("."); // 从后匹配"."
        String newFileName = uuid + originFileName.substring(beginIndex); // 新文件名,如:uuid.xlsx
        String destFileName = UploadFilePath + File.separator + newFileName; // 完整文件名 = 存储路径 + 原文件名

        // 复制文件到指定目录
        File destFile = new File(destFileName);
        destFile.getParentFile().mkdirs();
        file.transferTo(destFile);

        // 返回文件名
        return CommonResponse.ok(newFileName);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return CommonResponse.fail(e.getMessage());
    } catch (IOException e) {
        e.printStackTrace();
        return CommonResponse.fail(e.getMessage());
    }
}

二、前端代码

(1)视图页面(/src/view/Example/UploadFormData/index.vue)

<template>
  <div>
    <el-dialog
      width="400"
      title="导入 Excel"
      class="import-excel-dialog"
      align-center
      destroy-on-close
      draggable
      center
      v-model="importExcelDialog.isVisible"
      :before-close="handleCloseImportExcelDialogClick"
    >
      <div>
        <p style="margin: 0 auto 7px 0; font-size: 13px">请上传Excel文件</p>
        <el-upload
          ref="importExcelUploadRef"
          drag
          action=""
          :limit="1"
          :on-exceed="handleUploadFileExceed"
          :on-change="handleUploadFileChange"
          :auto-upload="false"
        >
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="el-upload__text" style="font-size: 13px">
            拖动文件到此处进行上传 或 <em>点击上传</em>
          </div>
          <template #tip>
            <div class="el-upload__tip">支持格式 : xls/xlsx/xlsm</div>
          </template>
        </el-upload>
 
        <el-input
          size="small"
          v-model="importExcelDialog.username"
          style="width: 100%; background-color: #eee"
          placeholder="请输入用户"        
        >
        </el-input>
      </div>
 
      <template #footer>
        <div>
          <el-button size="small" type="primary" @click="handleUploadFileComfirm($event)">
            <el-icon :size="18" style="margin-right: 5px"><Check /></el-icon>
            <small>确定</small>
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
 
<script>
export default {
  data: () => {
    return {
      // 导入Excel弹窗
      importExcelDialog: {
        isVisible: false,
        username: '帅龍之龍',
        uploadFileList: [], // 校验通过的上传文件列表
      },
    }
  },
  created() {
    // ...
  },
  mounted() {
    this.handleOpenImportExcelDialogClick()
  },
  methods: {
    /**
     * 打开导入Excel弹窗事件句柄
     */
    handleOpenImportExcelDialogClick() {
      this.importExcelDialog.isVisible = true
    },
 
    /**
     * 文件上传 - 文件超过句柄方法
     */
    async handleUploadFileExceed(files, uploadFiles) {
      console.log(
        '%c 文件超过句柄方法 %c handleUploadFileExceed',
        'padding: 1px; background-color: #35495e; color: #fff',
        'padding: 1px; background-color: #5e7ce0; color: #fff',
      )
      console.log('%c ∟ %c files %c =>', 'text-indent: 10px', 'padding: 1px; background-color: #41b883; color: #fff', 'color: #000', files)
      console.log('%c ∟ %c uploadFiles %c =>', 'text-indent: 10px', 'padding: 1px; background-color: #41b883; color: #fff', 'color: #000', uploadFiles)
 
      const refs = await this.$refs
      const importExcelUploadRef = refs.importExcelUploadRef
 
      const uploadFile = files[0]
      const fileName = uploadFile.name // xxxxxx.xlsx
      const index = fileName.lastIndexOf('.')
      const type = fileName.substring(index) // .xlsx
 
      if (!(type == '.xls' || type == '.xlsx' || type == '.xlsm')) {
        this.$message({ message: '文件格式错误,应为 xls/xlsx/xlsm 类型文件', type: 'warning', duration: 3000 })
 
        // 清空
        importExcelUploadRef.clearFiles()
      } else {
        // 清空
        importExcelUploadRef.clearFiles()
 
        // 回显
        const file = files[0]
        importExcelUploadRef.handleStart(file) 
 
        // 文件上传列表重新赋值
        this.importExcelDialog.uploadFileList = []
        this.importExcelDialog.uploadFileList.push(uploadFile)
      }
    },
 
    /**
     * 文件上传 - 文件改变句柄方法
     */
    async handleUploadFileChange(uploadFile, uploadFiles) {
      console.log(
        '%c 文件改变句柄方法 %c handleUploadFileChange',
        'padding: 1px; background-color: #35495e; color: #fff',
        'padding: 1px; background-color: #5e7ce0; color: #fff',
      )
      console.log('%c ∟ %c uploadFile %c =>', 'text-indent: 10px', 'padding: 1px; background-color: #41b883; color: #fff', 'color: #000', uploadFile)
      console.log('%c ∟ %c uploadFiles %c =>', 'text-indent: 10px', 'padding: 1px; background-color: #41b883; color: #fff', 'color: #000', uploadFiles)
 
      const refs = await this.$refs
      const importExcelUploadRef = refs.importExcelUploadRef
      
      const fileName = uploadFile.name // xxxxxx.xlsx
      const index = fileName.lastIndexOf('.')
      const type = fileName.substring(index) // .xlsx
 
      if (!(type == '.xls' || type == '.xlsx' || type == '.xlsm')) {
        this.$message({ message: '文件格式错误,应为 xls/xlsx/xlsm 类型文件', type: 'warning', duration: 3000 })

        // 清空
        importExcelUploadRef.clearFiles()
      } else {
        // 文件上传列表重新赋值
        this.importExcelDialog.uploadFileList = []
        this.importExcelDialog.uploadFileList.push(uploadFile)
      }
      console.log('%c ∟ %c uploadFileList %c =>', 'text-indent: 10px', 'padding: 1px; background-color: #41b883; color: #fff', 'color: #000', this.importExcelDialog.uploadFileList)
    },
 
    /**
     * 文件上传 - 确认上传句柄方法
     */
    async handleUploadFileComfirm(evt) {
      this.$elementUtil.handleElButtonBlur(evt)
 
      if (this.importExcelDialog.uploadFileList.length == 0) {
        this.$message({ message: '请上传文件', type: 'warning', duration: 3000 })
        return
      }

      let formData = new FormData()
      this.importExcelDialog.uploadFileList.map(uploadFile => {
        formData.append('file', uploadFile.raw)
      })
      formData.append('username', this.importExcelDialog.username.trim())

      this.$axios.post(
        `/sz-senwill-sky/api/uploadSingleFile`,
        formData,
        {
          headers: {
            'Access-Control-Allow-Origin': '*',
            'Content-Type': 'multipart/form-data',
            'Authorization': 'Bearer token'
          },
        }
      )
      .then((res) => {
        console.log('get =>', res)
        if (res.status == 200 && res.data) {
          const result = res.data
          if (result.code == 200 && result.success) {
            this.$elementUtil.handleAutoCloseMessage(`上传成功,新文件名为:${result.data}`, 'success', 5, true)
          } else {
            this.$elementUtil.handleAutoCloseMessage(`上传失败,服务端出错,请联系管理员`, 'error', 5, true)
          }
        }

        setTimeout(() => { this.importExcelDialog.isVisible = false }, 1000)
      }).catch(err =>{
        this.$elementUtil.handleAutoCloseMessage(err, 'error', 5, true)
        console.error(err)
      })

      const refs = await this.$refs
      const importExcelUploadRef = refs.importExcelUploadRef

      // 清空
      importExcelUploadRef.clearFiles()

      // 文件上传列表重置
      this.importExcelDialog.uploadFileList = []
    },
 
    /**
     * 关闭导入Excel弹窗事件句柄
     */
    handleCloseImportExcelDialogClick() {
      this.importExcelDialog.isVisible = false
    },
  }
}
</script>
 
<style lang="less" scoped>
  :deep(.import-excel-dialog) {
 
    .el-dialog__header {
      margin-right: 0;
      padding: 25px 20px;
      border-bottom: 1px solid #efefef;
 
      .el-dialog__title {
        font-size: 15px;
        word-wrap: break-word;
        word-break: normal
      }
 
      .el-dialog__headerbtn {
        top: 15px;
        font-size: 20px;
      }
    }
 
    .el-dialog__body {
      padding: calc(var(--el-dialog-padding-primary) + 10px) var(--el-dialog-padding-primary);
 
      .el-select {
 
        .el-input {
        
          .el-input__wrapper {
            background-color: transparent;
          }
        }
      }
 
      .el-input {
        
        .el-input__wrapper {
          background-color: #eee;
        }
      }
    }
 
    .el-dialog__footer {
      padding: var(--el-dialog-padding-primary);
      border-top: 1px solid #efefef;
    }
  }
</style>

三、效果如下 ~

基于SpringBoot + Vue实现单个文件上传(带上Token和其它表单信息)的前后端完整过程

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/151117.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!