VUE+servlet上传多文件实践

前言:

网上有很多使用el-upload上传多个文件的文章,但是百度了一下,要么就是代码贴的不完整,要么就是完全不能使用的。找了一圈,最后竟然找不到一个可用的。所以最后只能选择自己造轮子了。

一:我的方案

1.1 现成的方案:

网上通用的方案是放弃本身的action上传,通过指定http-request方法。这样点击提交后就不会发起action请求。然后通过form表单的方式拼接参数,添加文件然后进行请求。

我尝试了这种方式,发现后台无法正常的接受前端发过来的请求,发过来的请求都是只包含文件名,但是不包含文件内容。所以只能无奈放弃这种方案了。

1.2 我的方案:

我的方案是这样的,支持多文件上传,这样多文件,点击上传的时候会触发多次action请求。

在成功回调里面计数,如果成功的次数等于待上传的个数,那就是成功,否则是失败。

二:实现-VUE部分

首先是布局的部分,就是正常的使用el-upload上传。

<template>
  <div class="login-view">
    <div class="login-form">
     ...无用代码略过

      <el-form ref="form" label-position="left" :model="form" class="el-form">
        <el-form-item label="上传文件:" prop="excelFile">
          <el-upload
            class="el-upload"
            ref="upload"
            multiple
            :action="this.SERVE_URL + 'upload_img'"
            name="excelFile"
            drag
            :data="upData"
            :on-change="onUploadChange"
            :file-list="fileList"
            :on-error="uploadFalse"
            :on-success="uploadSuccess"
            :auto-upload="false"
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
            <!-- <el-button slot="trigger" size="small" >选取文件</el-button> -->
          </el-upload>
        </el-form-item>
      </el-form>
      <div class="button-view">
        <!-- <p>头像: <input type="file" id="files" ref="refFile" multiple="multiple" v-on:change="fileLoad" /></p> -->
        <button @click="submitUpload">提交</button>
        <button @click="closePage">关闭</button>
      </div>
    </div>
  </div>
</template>

几个参数详细解释下,方便小白理解:

1.multiple代表支持多文件上传,选择了这个选项后,点击提交如果有多个文件,会触发多次action的请求。

2.action是上传的服务器地址接口名。

3.on-change代表选择文件后的回调方法,请注意,不仅仅是选择文件后,上传成功时也会触发这个方法。

4.file-list对应的是文件清单

5.on-success代表上传成功时回调的接口

6.au-upload="false"代表不自动上传

然后是js部分:

<script>

export default {
  components: {},
  props: {},
  data() {
    return {
      baseUrl: this.SERVE_URL + 'upload_img',
      isJump: false,
      accountInfo: {},
      imageUrl: '',
      imageFile: {},
      form: {},
      fileList: [],//等待上传的集合
      uploadSucessList: []//上传成功的集合
    }
  },
  computed: {
    upData: function () {
      return this.form
    }
  },
  created() {
    var accountInfo = this.$route.params
    this.accountInfo = accountInfo
  },

  mounted() {},
  methods: {
    onUploadChange(file) {
      if (file.status != 'ready') {
        return
      }
      this.fileList.push(file)
    },
    //文件上传成功触发
    uploadSuccess(response) {
      console.log(response)

      if (response.data.status == 200) {
        this.uploadSucessList = this.uploadSucessList.concat(response.data.imgList)
        if (this.uploadSucessList.length == this.fileList.length) {
          this.requestRegister(this.uploadSucessList)
        }
      } else {
        this.$message({
          message: '导入失败',
          type: 'error'
        })
      }
    },
    //文件上传失败触发
    uploadFalse() {
      this.$message({
        message: '文件上传失败!',
        type: 'error'
      })
    },

    //表单取消
    onCancel() {
      this.$refs.form.resetFields()
    },
    requestRegister(imgUrlList) {
       //注册新用户的逻辑
      debugger
      var that = this
      var imgUrl = '';
      imgUrlList.forEach(function (img) {
        imgUrl = imgUrl + img.imgUrl+";"
      })
       this.accountInfo.imgUrl = imgUrl
      const data = {
        accountInfo: JSON.stringify(this.accountInfo)
      }     
      //这里
      console.log('account:' + JSON.stringify(data))
      //请求登录
      this.$apis.user
        .requestSet(data)
        .then(response => {
          debugger
          console.log(response.message)
          this.$message({
            message: response.message
          })
          setTimeout(() => {
            that.$router.go(-1)
          }, 1000)
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => {
          this.showLoading = false
        })
    },
    //表单提交
    submitUpload() {
      if (this.fileList.length == 0) {
        this.requestRegister([])
        return
      }
      //触发组件的action
      this.$refs.upload.submit() //主要是这里
    },
    closePage() {
      this.$router.go(-1)
    }
  }
}
</script>

最后是CSS部分:

<style lang="scss" scoped>
.login-view {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  text-align: center;
  // background-color: rgb(51, 51, 51);
  background-color: #fff;
  display: flex;
  flex-direction: column;
  justify-content: center;
  justify-items: center;
  align-items: center;
}
.login-form {
  display: flex;
  flex-direction: column;
  justify-content: left;
  justify-items: left;
  width: 50%;
  border: 1px solid #000;
  padding: 50px;
  p {
    display: flex;
    flex-direction: row;
    justify-content: left;
    label {
      width: 100px;
      text-align: right;
    }
    input {
      width: 400px;
    }
    b {
      width: 100%;
    }
  }
  .el-form {
    padding-left: 30px;
    margin-top: 10px;
  }
  .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;
  }
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
}
.button-view {
  display: flex;
  flex-direction: row;
  padding-left: 20%;
  padding-right: 20%;
  width: 100%;
  align-content: flex-start;
  justify-content: space-between;
  align-items: flex-start;
  button {
    font-size: 15px;
    padding: 10px 30px 10px 30px;
  }
}
</style>

三:实现后台部分

后台我使用的是comons-fileupload框架。

核心代码如下,想看完整代码可以直接跳到第四章。

request转换成FileItem对象

  public List<FileItem> readAllParams(HttpServletRequest request) throws Exception {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        List<FileItem> fileItems = upload.parseRequest(request);
        return fileItems;
    }

保存图片到本地,并返回生成的链接。(我图片直接放到了项目目录下了)

 public JSONObject saveImage(ImageModel imageModel, String realPath) throws Exception {
        JSONObject data = new JSONObject();

        String path = realPath + "img/";
        String url = Config.SERVE_URL_RELEASE + "/img/";
        if (realPath.contains("out")) {
            //开发环境
            path = realPath + "img/";
            url = Config.SERVE_URL_DEBUG + "/img/";
        }
        if (imageModel.fileItems.size() > 0) {
            for (ImgFile imgFile : imageModel.fileItems) {
                imgFile.imgPath = path + imgFile.imgName;
                imgFile.imgUrl = url + imgFile.imgName;
                File saveImgFile = new File(imgFile.imgPath);
                if (!saveImgFile.getParentFile().exists()) {
                    saveImgFile.getParentFile().mkdirs();
                }
                imgFile.fileItem.write(saveImgFile);
            }
            JSONArray imgList = new JSONArray();
            for (ImgFile imgFile : imageModel.fileItems) {
                JSONObject imgJson = new JSONObject();
                imgJson.put("imgName", imgFile.imgName);
                imgJson.put("imgPath", imgFile.imgPath);
                imgJson.put("imgUrl", imgFile.imgUrl);
                imgList.add(imgJson);
            }
            data.put("status", 200);
            data.put("imgList", imgList);
        } else {
            data.put("status", 500);
        }
        return data;
    }

四:代码完整链接

项目地址:

GitHub - aa5279aa/StaffManagerWeb: 员工管理系统

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Vue是一种用于构建用户界面的JavaScript框架,而Servlet是Java语言的服务器端技术。要实现VueServlet的结合完成文件上传功能,需要以下步骤: 1. 首先,在Vue的组件中创建一个文件上传的表单,该表单包含一个文件选择框和一个提交按钮。 2. 当用户选择要上传文件后,Vue将获取到文件对象,并以FormData的形式将文件数据和其他表单数据一起发送给服务器。 3. 在Vue中,可以使用axios或其他类似库向服务器发送HTTP请求。创建一个POST请求,将FormData对象作为请求的数据,并将请求发送到Servlet的URL。 4. 在Servlet中,创建一个POST方法的处理函数。在该处理函数中,获取到上传文件和其他表单数据。可以使用HttpServletRequest的getPart方法来获取文件,使用getParameter方法来获取其他表单数据。 5. 使用文件的InputStream将上传文件数据写入到服务器的指定位置。可以使用FileOutputStream将文件数据写入到磁盘上的指定文件夹中。 6. 处理完文件上传后,可以通过HttpServletResponse返回给前端一个上传成功的消息或者其他需要的数据。 在VueServlet的结合实现文件上传功能时,需要注意跨域问题。可以在Servlet的响应中设置Access-Control-Allow-Origin头部信息,允许来自Vue前端的跨域请求。 以上是使用VueServlet实现文件上传的基本步骤,根据具体的需求和情况可以进行相应的调整和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

失落夏天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值