springboot+layui实现带进度条带参数上传

直接进入主题

layui有很多很好用的组件给我们使用,这里前端使用layui提供的进度条组件

后端使用springboot监听传入的byte,然后返回给前端,最终实现进度条功能

layui官网  https://www.layui.com/

springboot官网  http://spring.io/projects/spring-boot

1.后端

首先定义一个进程的实体类,关于进度条的数据在这里定义

package com.yuxiao.springboot.upload.entity;

import org.springframework.stereotype.Component;


/**
 * 上传进度实体类
 */
@Component
public class ProgressEntity {
    private long readBytes = 0L; //到目前为止读取文件的比特数
    private long allBytes = 0L;    //文件总大小
    private int currentIndex;      //目前正在读取第几个文件

    public long getReadBytes() {
        return readBytes;
    }

    public void setReadBytes(long readBytes) {
        this.readBytes = readBytes;
    }

    public long getAllBytes() {
        return allBytes;
    }

    public void setAllBytes(long allBytes) {
        this.allBytes = allBytes;
    }

    public int getCurrentIndex() {
        return currentIndex;
    }

    public void setCurrentIndex(int currentIndex) {
        this.currentIndex = currentIndex;
    }

    @Override
    public String toString() {
        return "ProgressEntity{" +
                "readBytes=" + readBytes +
                ", allBytes=" + allBytes +
                ", currentIndex=" + currentIndex +
                '}';
    }
}

然后定义一个listener来监听上传文件的相关信息,总大小,已读取的文件等等

package com.yuxiao.springboot.upload.listener;


import com.yuxiao.springboot.upload.entity.ProgressEntity;
import org.apache.commons.fileupload.ProgressListener;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;

@Component
public class UploadProgressListener implements ProgressListener {

    private HttpSession session;

    public void setSession(HttpSession session){
        this.session = session;
        ProgressEntity pe = new ProgressEntity();
        session.setAttribute("uploadStatus", pe);
    }


    /**
     *  设置当前已读取文件的进度
     * @param readBytes 已读的文件大小(单位byte)
     * @param allBytes 文件总大小(单位byte)
     * @param index 正在读取的文件序列
     */
    @Override
    public void update(long readBytes, long allBytes, int index) {
        ProgressEntity pe = (ProgressEntity) session.getAttribute("uploadStatus");
        pe.setReadBytes(readBytes);
        pe.setAllBytes(allBytes);
        pe.setCurrentIndex(index);
    }
}

再定义一个配置类,yua源源不断的把进度信息放到session中

package com.yuxiao.springboot.upload.config;

import com.yuxiao.springboot.upload.listener.UploadProgressListener;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Component
public class YuxiaoMultipartResolver extends CommonsMultipartResolver {

    @Autowired
    private UploadProgressListener progressListener;

    @Override
    protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
        String encoding = super.determineEncoding(request);
        progressListener.setSession(request.getSession());
        FileUpload fileUpload = prepareFileUpload(encoding);
        fileUpload.setProgressListener(progressListener);
        try {
            List<FileItem> fileItemList =  ((ServletFileUpload)fileUpload).parseRequest(request);
            return super.parseFileItems(fileItemList, encoding);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        return null;
    }
}

最后写控制层,在点击文件上传之后,需要不断访问获得经度

package com.yuxiao.springboot.upload.controller;


import com.yuxiao.springboot.upload.entity.ProgressEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件上传及进度测试
 */
@Controller
public class UploadController {


    /**
     * 显示文件上传页
     * @return
     */
    @RequestMapping("uploadPage")
    public String showUploadPage(){
        return "uploadPage";
    }

    /*
     * 文件上传
     * <p>Title: upload</p>  
     * <p>Description: </p>  
     * @param file
     * @return
     */
    @PostMapping("upload")
    @ResponseBody
    public Map<String, Object> upload(MultipartFile file){
        Map<String, Object> result = new HashMap<>();
        if (file != null && !file.isEmpty()){
            try {
                file.transferTo(new File("d:/"+file.getOriginalFilename()));
                result.put("code", 200);
                result.put("msg", "success");
            } catch (IOException e) {
                result.put("code", -1);
                result.put("msg", "文件上传出错,请重新上传!");
                e.printStackTrace();
            }
        } else {
            result.put("code", -1);
            result.put("msg", "未获取到有效的文件信息,请重新上传!");
        }
        return result;
    }


    /**
     * 获取文件上传进度
     * @param request
     * @return
     */
    @RequestMapping("getUploadProgress")
    @ResponseBody
    public ProgressEntity getUploadProgress(HttpServletRequest request){
        return (ProgressEntity) request.getSession().getAttribute("uploadStatus");
    }

}

最后是前端页面 elem是上传的文件,bindAction是触发按钮  url是后端接口地址,data可以设置上传携带参数,progress:function中就可以获得上传进度。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <link rel="stylesheet" href="/plugins/layui-v2.2.5/css/layui.css" media="all">
    <script src="/plugins/layui-v2.2.5/layui.js"></script>
</head>
<body>

<!--<input type="hidden" id="scopeType" name="scopeType" value="1">-->
<!--<input type="hidden" id="scopeId" name="scopeId" value="5">-->
<!--<input type="hidden" id="appCatagory" name="appCatagory" value="1">-->

<button type="button" class="layui-btn" id="addFile">
    <i class="layui-icon">&#xe67c;</i>添加文件
</button>

<button type="button" class="layui-btn" id="upload">上传</button>
<div class="layui-progress layui-progress-big" lay-showpercent="true" lay-filter="uploadProgressBar">
    <div class="layui-progress-bar" lay-percent="0%"></div>
</div>
</body>
<script>
    layui.use(["layer","form", "upload","jquery","element"], function () {
        // 注意:为了动态显示进度条,必须加载element组件
        var layer = layui.layer, upload = layui.upload, $ = layui.jquery, element = layui.element;

        upload.render({
            accept : "file",
            elem : "#addFile",
            auto : false,   //关闭文件自动上传
            bindAction : "#upload", //文件上传触发按钮
            url : "upload",
            data:{
                scopeType:  1,
                scopeId:  5,
                appCatagory:  1
            },//设置上传时携带的参数,后端可以用 String appCatagory = request.getParameter("appCatagory");接收
            progress:function(value){//上传进度回调 value进度值
                element.progress('uploadProgressBar', value+'%')//设置页面进度条
            },
            before : function (obj) {
               /* var intId = setInterval(function () {
                    getUploadStatus(intId);
                }, 1000); //每秒向服务端获取一次当前上传进度情况*/
            },
            done : function (res, index, upload) {
                // if(res.code != 200){
                //     layer.open({
                //         icon : 2,
                //         skin : "layui-layer-molv",
                //         content : res.msg
                //     });
                // }
                console.log(res);
            },
            error : function (res) {
                
            }
        });

    });
</script>
</html>

实现效果

最后附上源码  https://github.com/Yanyf765/upload

猜你喜欢

转载自blog.csdn.net/u012954380/article/details/82219814