The front-end vue elementUI upload upload component encapsulates & multiple file uploads & progress bar, and the back-end servlet request.getPart() receives file information

vue upload component

Select multiple files to upload
Listen through the axios请求 onUploadProgress method
on-progress on-successUse these two hook functions to implement the progress bar below There are corresponding functions.
This article uploads each file with one request.
You can also upload multiple files with one request. You need to add file traversal to formIn the form, the backend uses request.getParts(); to obtain the collection, which can be modified if necessary.

Official website address: https://element.eleme.cn/#/zh-CN/

<template>

  <div>
    <!-- multiple 允许上传多个文件 -->
    <el-upload
        :disabled="defaultDisabled"
        ref="upload"
        :multiple="multiFile"
        action=""
        :auto-upload="false"
        :file-list = "fileList"
        :http-request="uploadFile"
        :on-change="changeFileLength"
        :on-progress="uploadFileProcess"
        :on-success="handleFileSuccess"
        :on-preview = "handleFilePreview"
        :on-remove = "handleFileRemove"
        :before-upload = "beforeFileUpload"
        :before-remove = "beforeFileRemove"
        :limit="limit"
        :on-exceed = "handleFileExceed">
      <div v-if="!defaultDisabled">
        <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
        <el-button style="margin-left: 10px;" size="small" type="success" @click.stop="upload">上传到服务器</el-button>
      </div>
      <div slot="tip" class="el-upload__tip">文件大小不能超过1GB</div>
    </el-upload>
  </div>

</template>

<script>
module.exports = {
    
    
  name: "upload",
  props:{
    
    
    data:{
    
    
      type:Array,
      default:[],
    },
    businessId:{
    
    
      type:String,
      default:"",
    },
    businessType:{
    
    
      type:String,
      default:"",
    },
    filePath:{
    
    
      type:String,
      required:true, //必须指定路径
      default:"",
    },
    fileSize:{
    
    
      type:Number,
      default:(1024 * 1024 * 1024) // 默认1GB
    },
    fileNumber:{
    
    
      type:Number,
      default: 5 //默认5个文件
    },
    disabled:{
    
    
      type:Boolean,
      default:false,
    },
    multiple:{
    
    
      type:Boolean,
      default:true,
    }

  },

  data(){
    
    
    return {
    
    
      fileList: this.data, // 文件列表
      size:this.fileSize,// 文件大小限制
      limit:this.fileNumber, // 文件数量
      path:this.filePath, // 上传路径
      defaultDisabled: this.disabled, // 是否禁用
      formId: this.businessId, //业务主键
      formTable: this.businessType, //业务表
      multiFile:this.multiple //默认上传多个文件
    }
  },

  created(){
    
    
    this.getFileList();
  },
  methods:{
    
    

    //文件上传前调用,如果返回false 和 失败状态 就会停止上传 并移除fileList的文件
    beforeFileUpload(file) {
    
    
      //校验文件大小
      if (file.size >= this.size) {
    
    
        //单位GB
        let gb = (file.size / this.size).toFixed(4);
        this.$notify.error({
    
    
          title: '错误',
          message:  `${
      
      file.name} 文件大小超出${
      
      gb}GB,请重新选择!`
        });
        return false;
      }
    },
    // 将文件名称进行编码 后台进行解码
    changeFileLength(file, fileList){
    
    
      let fileName = encodeURI(file.name) // 如果可以上传多个文件,这里需要用fileList.forEach()处理
      let newFile = new File([file.raw],fileName);
      newFile.uid = file.uid; // new File 没有uid属性,会导致组件底层报错,这里手动加上
      file.raw = newFile;  // 替换file的数据
    },

    // 用户点击上传调用
    async upload(){
    
    
      // 触发上传 调用配置 :http-request="uploadFile"
      // 即触发 uploadFile函数
      await this.$refs.upload.submit();
      // 上传完成后执行的操作 ...
    },
    // 该函数调用多次
    // 每次param参数传入一个文件
    uploadFile(param){
    
    
      // 创建FormData上传
      let form = new FormData();
      form.append('file', param.file)
      form.enctype = "multipart/form-data";
      // 将附加信息添加至FormData
      form.append("filePath", this.path);
      form.append("businessId", this.formId);
      form.append("businessType", this.formTable);
        //上传操作
      this.uploadAttach(form,param).then(res => {
    
    
          /*上传成功处理*/
          param.onSuccess(res);
      }).catch(err => {
    
    
          /*报错处理*/
          this.$message.error(param.file.name + "上传错误");
          param.onSuccess(err);
          for (let i = 0; i < this.fileList.length; i++) {
    
    
            if (param.file.name === this.fileList[i].name) {
    
    
              this.fileList.splice(i, 1);
              break;
            }
          }
        });
      // }
    },
    // 上传文件
    uploadAttach(data,fileObject){
    
    
      return axios({
    
    
        method:'post',
        headers: {
    
    "Content-Type": "multipart/form-data"},
        url:"/servlet/uploadServlet",//自定义上传url
        data:data,
        onUploadProgress: progressEvent => {
    
    
          fileObject.progressFlag = true;
          fileObject.successFlag = true;
          let percent=(progressEvent.loaded / progressEvent.total * 100) | 0
          fileObject.onProgress({
    
    percent});//调用uploader的进度回调
        }
      })
    },
    // 文件上传过程中的函数(在这里获取进度条的进度)
    uploadFileProcess(event, file, fileList) {
    
    
      this.fileList = fileList;
      for (let i = 0; i < this.fileList.length; i++) {
    
    
        if(file.name === this.fileList[i].name){
    
    
          this.fileList[i].progressFlag = true;
          this.fileList[i].successFlag = false;
          if(event.percent != 100){
    
    
            this.fileList[i].progressPercent = event.percent;
          }
          break;
        }
      }
    },
    // 文件上传成功的函数(用于文件上传成功之后的逻辑处理)
    handleFileSuccess(res,file,fileList){
    
    
      this.fileList = fileList;
      for (let i = 0; i < this.fileList.length; i++) {
    
    
        if(file.name === this.fileList[i].name){
    
    
          this.fileList[i].progressFlag = true;
          if(file.status == 'success' && res.data.code == 200){
    
    
            this.fileList[i].successFlag = true;
            res.data = res.data.data;
          }else{
    
    
            this.fileList[i].successFlag = false;
            this.fileList.splice(i, 1);
          }
          break;
        }
      }
    },
    //查看文件
    handleFilePreview(file){
    
    
      console.log(file);
    },
    //删除文件
    handleFileRemove(file,fileList){
    
    
      console.log(file);
    },
    //文件数超出函数
    handleFileExceed(files,fileList){
    
    
      this.$notify.error({
    
    
        title: '错误',
        message:  `只能选择${
      
      this.limit}个文件,请重新选择文件!`
      });
    },
    //文件删除前的操作
    beforeFileRemove(file, fileList){
    
    },
    // 后台获取已经上传的文件列表
    getFileList(){
    
    
      if(this.businessId === "") return;
      axios.get("/servlet/uploadServlet",{
    
    
        businessId:this.businessId,
      }).then(res => {
    
    
        if(res.data.code === 200) this.fileList = res.data.data
      }).catch(err=>{
    
    
        this.$message.error("请求失败,请稍后再试!");
      })
    },
  }
}
</script>

<style scoped>

</style>

java servlet request

  • @MultipartConfigAfter using this annotation, use the following method to obtain the file
  • Part part = request.getPart("file")What is obtained is a single file
  • Collection<Part> parts = request.getParts();Multiple files obtained
package com.kaiyue.detection.upload;
import com.App.Servlet.AppResponse;
import com.alibaba.fastjson.JSONObject;
import com.kaiyue.common.BeanFactory;
import com.kaiyue.common.resource.AppConfig;
import com.kaiyue.common.util.DateUtil;
import com.kaiyue.jpf.attachment.service.FileService;
import com.kaiyue.jpf.common.resource.CommonResource;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.*;
import java.net.URLDecoder;
import java.util.Collection;
import java.util.HashMap;
import java.util.Random;

@WebServlet(name = "uploadServlet", urlPatterns = "/servlet/uploadServlet")
@MultipartConfig
public class uploadServlet extends HttpServlet {
    
    
  @Override
  public void destroy() {
    
    
    super.destroy();
  }

  @Override
  protected void doGet(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {
    
    
    this.doPost(request, response);
  }

  /**
   * @param request
   * @param response
   */
  @Override
  protected void doPost(HttpServletRequest request,
                        HttpServletResponse response) throws IOException, ServletException {
    
    
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
    response.setContentType("text/html;charset=utf-8");
    FileService fileService = (FileService) BeanFactory.getBeanByName("fileService");

    AppResponse res = new AppResponse();

    request.setCharacterEncoding("UTf-8");
    String businessId = request.getParameter("businessId");//业务主键
    String filePath = request.getParameter("filePath");//保存路径
    String businessType = request.getParameter("businessType");//业务表名

    HashMap<String, String> returnMap = new HashMap<>();
    String fileId = "";//文件信息的主键
    try {
    
    
      //获取文件对象
      Part part = request.getPart("file");
      //获取请求头,请求头的格式:form-data; name="file"; filename="snmp4j--api.zip"
      String header = part.getHeader("content-disposition");
      String fileName = getFileName(header);
      fileName = URLDecoder.decode(fileName, "UTF-8");
//获取配置的磁盘根目录
      String path = AppConfig.getRootPath();
      Random random = new Random();
      int number = random.nextInt(1000);
//防止上传的文件重名 取一个新的名字
      String newFileName = fileName.substring(0, fileName.lastIndexOf(".")) + DateUtil.getTimeStampId() + number +
              fileName.substring(fileName.lastIndexOf("."));
      File dir = new File(path + CommonResource.FILE_SEPARATOR + filePath + CommonResource.FILE_SEPARATOR);
      if (!(dir.exists())) {
    
    
        dir.mkdirs();
      }

//写入磁盘
      uploadFile(part, dir + CommonResource.FILE_SEPARATOR + newFileName);
      String projectId = "";
      String userId = "";
//保存到数据库
      fileId = fileService.addFileRecord(fileName, filePath + CommonResource.FILE_SEPARATOR + newFileName, userId,
              businessType, businessId, projectId, part.getSize());

      returnMap.put("fileId", fileId);//主键
      returnMap.put("businessId", businessId);
      res.setData(returnMap);
      res.setCode(AppResponse.OK);
      res.setMessage("上传成功!");
    } catch (Exception e) {
    
    
      res.setData(returnMap);
      res.setCode(AppResponse.PARAMETER_ERR);
      res.setMessage("上传失败!");
      e.printStackTrace();
    }

    PrintWriter out = response.getWriter();
    out.println(JSONObject.toJSONString(res));
    out.flush();
    out.close();
  }

  /**
   * 根据请求头解析出文件名
   * 请求头的格式:火狐和google浏览器下:form-data; name="file"; filename="snmp4j--api.zip"
   * IE浏览器下:form-data; name="file"; filename="E:\snmp4j--api.zip"
   *
   * @param header 请求头
   * @return 文件名
   */
  public String getFileName(String header) {
    
    
    /**
     * String[] tempArr1 = header.split(";");代码执行完之后,在不同的浏览器下,tempArr1数组里面的内容稍有区别
     * 火狐或者google浏览器下:tempArr1={form-data,name="file",filename="snmp4j--api.zip"}
     * IE浏览器下:tempArr1={form-data,name="file",filename="E:\snmp4j--api.zip"}
     */
    header = header.substring(header.lastIndexOf("\\") + 1).replaceAll("\"", "");

    String[] tempArr1 = header.split(";");
    /**
     *火狐或者google浏览器下:tempArr2={filename,"snmp4j--api.zip"}
     *IE浏览器下:tempArr2={filename,"E:\snmp4j--api.zip"}
     */

    String[] tempArr2 = tempArr1[2].split("=");

    //获取文件名,兼容各种浏览器的写法
    String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\") + 1).replaceAll("\"", "");
    return fileName;
  }


  private void uploadFile(Part part, String path)
          throws Exception {
    
    

    InputStream stream = null;
    OutputStream out = null;
    stream = part.getInputStream();
    out = new FileOutputStream(path);
    int bytesRead = 0;
    byte[] buffer = new byte[8192];
    while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
    
    
      out.write(buffer, 0, bytesRead);
    }
    out.close();
    stream.close();
  }
}

Effect

The file is relatively large
renderings

Guess you like

Origin blog.csdn.net/web_houzhanguo/article/details/131276571