springboot带有进度条的上传

Posted zincredible

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot带有进度条的上传相关的知识,希望对你有一定的参考价值。

1.pom.xml配置

application.yml

 

server: 
  port: 7007
  tomcat: 
  uri-encoding :  UTF-8
spring: 
  application: 
    name: push-svc-demo
  thymeleaf: 
    encoding: UTF-8
    cache: false
    mode: LEGACYhtml5
  data: 
    mongodb:
       host: 127.0.0.1
       port: 27017
       database: mydb
debug: false

 

<parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>1.5.10.RELEASE</version>
      <relativePath/>
  </parent>

  <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
     <java.version>1.8</java.version>
  </properties>
   
  <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-devtools</artifactId>
         <optional>true</optional>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-thymeleaf</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
      <dependency> 
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
      </dependency>
      <!--添加文件上传支持-->
      <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
      </dependency>
      <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
     </dependency>
     <!--添加html5支持-->
     <dependency> 
            <groupId>net.sourceforge.nekohtml</groupId> 
            <artifactId>nekohtml</artifactId>
      </dependency> 
  </dependencies>
  
  <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
  </build>

2.进程类

public class Progress
{
    private long bytesRead; //已读取文件的比特数
    private long contentLength;//文件总比特数
    private long items; //正读的第几个文件

    public long getBytesRead()
    {
        return bytesRead;
    }

    public void setBytesRead(long bytesRead)
    {
        this.bytesRead = bytesRead;
    }

    public long getContentLength()
    {
        return contentLength;
    }

    public void setContentLength(long contentLength)
    {
        this.contentLength = contentLength;
    }

    public long getItems()
    {
        return items;
    }

    public void setItems(long items)
    {
        this.items = items;
    }
}

3.监听类

@Component
public class FileUploadProgressListener implements ProgressListener
{

    private HttpSession session;
    public void setSession(HttpSession session){
        this.session=session;
        Progress status = new Progress();//保存上传状态
        session.setAttribute("status", status);
    }
    @Override
    public void update(long bytesRead, long contentLength, int items) {
        Progress status = (Progress) session.getAttribute("status");
        status.setBytesRead(bytesRead);
        status.setContentLength(contentLength);
        status.setItems(items);

    }

}

4.

public class CustomMultipartResolver extends CommonsMultipartResolver
{
    // 注入第二步写的FileUploadProgressListener
    @Autowired
    private FileUploadProgressListener progressListener;

    public void setFileUploadProgressListener(FileUploadProgressListener progressListener)
    {
        this.progressListener = progressListener;
    }

    @Override
    public MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException
    {
        String encoding = determineEncoding(request);
        FileUpload fileUpload = prepareFileUpload(encoding);
        progressListener.setSession(request.getSession());// 问文件上传进度监听器设置session用于存储上传进度
        fileUpload.setProgressListener(progressListener);// 将文件上传进度监听器加入到 fileUpload 中
        try
        {
            List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
            return parseFileItems(fileItems, encoding);
        } catch (FileUploadBase.SizeLimitExceededException ex)
        {
            throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
        } catch (FileUploadException ex)
        {
            throw new MultipartException("Could not parse multipart servlet request", ex);
        }
    }
}

5.控制器

@RestController
public class FileController
{

    // private final static Logger logger =
    // LoggerFactory.getLogger(FileController.class);
    @Autowired
    private PushMsgRepository pushRep;
    public static void log(Object o)
    {
        System.out.println(o);
    }

    @RequestMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file)
    {
        if (file.isEmpty())
        {
            return "文件为空";
        }
        // 获取文件名
        String fileName = file.getOriginalFilename();
        System.out.println("上传的文件名为:" + fileName);
        // 获取文件的后缀名
        // String suffixName = fileName.substring(fileName.lastIndexOf("."));
        // logger.info("上传的后缀名为:" + suffixName);
        // 文件上传后的路径
        String filePath = null;
        try
        {
            filePath = new File("").getCanonicalPath() + "/tmp/uploadFile/";
        } catch (IOException e1)
        {
            e1.printStackTrace();
        }
        String tagFilePath = filePath + CommonUtil.getCurrentTime() + fileName;
        System.out.println("存储路径为:" + tagFilePath);
        // 解决中文问题,liunx下中文路径,图片显示问题
        // fileName = UUID.randomUUID() + suffixName;
        File dest = new File(tagFilePath);
        // 检测是否存在目录
        if (!dest.getParentFile().exists())
        {
            dest.getParentFile().mkdirs();
        }
        try
        {
            file.transferTo(dest);
            PushMsgEntity pushInfo=new PushMsgEntity();
            pushInfo.setFilePath(fileName);
            pushInfo.setUserName("深圳");
            pushRep.save(pushInfo);
            return fileName + "推送成功";
        } catch (IllegalStateException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return fileName + "推送失败";
    }

    @RequestMapping("/uploads")
    public Map<String, Object> uploadFiles(HttpServletRequest request)
    {
        Map<String, Object> result = new HashMap<String, Object>();
        List<MultipartFile> files2 = ((MultipartHttpServletRequest) request).getFiles("file");
        BufferedOutputStream stream = null;
        String uploadPath = "upload/";
        validatePath(uploadPath);
        result.put("fileLength", files2.size());
        int i = 0;
        for (MultipartFile file : files2)
        {
            String originalFilename = file.getOriginalFilename();
            i++;
            validateType(uploadPath);
            if (!file.isEmpty())
            {
                try
                {
                    byte[] bytes = file.getBytes();
                    stream = new BufferedOutputStream(new FileOutputStream(new File(uploadPath, originalFilename)));
                    stream.write(bytes);
                    result.put("file" + i, uploadPath + originalFilename);
                    stream.close();
                } catch (Exception e)
                {
                    result.put("message", originalFilename + "You failed to upload  => " + e.getMessage());
                }
            } else
            {
                result.put("message", originalFilename + "You failed to upload  because the file was empty.");
            }
        }
        return result;
    }

    /**
     * 验证上传的文件类型
     * 
     * @return
     */
    private Map<String, Object> validateType(String path)
    {
        Map<String, Object> result = new HashMap<String, Object>();
        File file = new File(path);
        if (!file.exists())
            file.mkdirs();
        return result;
    }

    /**
     * 验证上传的文件路径,没有则创建
     * 
     * @return
     */
    private void validatePath(String path)
    {

        File file = new File(path);
        if (!file.exists())
            file.mkdirs();
    }
    
    @RequestMapping("/showPushInfo")
    public List<PushMsgEntity> showAllPushInfo()
    {
        return pushRep.findAll(new Sort(Direction.DESC, "generateTime"));
    } 
}

6.启动类

@EnableAutoConfiguration(exclude = { MultipartAutoConfiguration.class })
@SpringBootApplication
public class Application extends SpringBootServletInitializer
{

    /*
     * 将 multipartResolver 指向我们刚刚创建好的继承 CommonsMultipartResolver 类的自定义文件上传处理类
     */
    @Bean(name = "multipartResolver")
    public MultipartResolver multipartResolver()
    {
        CustomMultipartResolver customMultipartResolver = new CustomMultipartResolver();
        return customMultipartResolver;
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
    {
        return application.sources(Application.class);
    }

    public static void main(String[] args)
    {
        SpringApplication.run(Application.class, args);
    }

}

7.页面测试

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Upload Files using XMLHttpRequest - Minimal</title>
<link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.css" />
<script src="/vendor/jquery/jquery-1.10.2.min.js"></script>
<script src="/vendor/bootstrap/js/bootstrap.min.js"></script>

</head>
<body class="container">
    <div id="wrapper">
        <div id="page-wrapper">
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">数据推送系统服务端</h1>
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">数据推送系统服务端</div>
                        <div class="panel-body">
                            <div class="row">
                                <div class="col-lg-6">
                                    <form role="form" action="javascript:void(0)">
                                        <div class="form-group">
                                            <label>模型文件选择</label> <input id="batchFile"
                                                class="btn btn-primary" name="file" type="file" />
                                            <div id="showFieInfo" class="form-group">
                                                <label id="upfileName"></label><br /> <label id="upfileSize"></label><br />
                                                <label id="upfileType"></label><br />
                                            </div>
                                            <!--  
                                            <label for="name">选择推送地域</label>
                                            <select class="form-control">
                                                <option>深圳</option>
                                                <option>东莞</option>
                                                <option>印度</option>
                                            </select> 
                                            -->
                                            <label for="name">选择推送的地域(可多选)</label> <select multiple
                                                class="form-control">
                                                <option>西安</option>
                                                <option>深圳</option>
                                                <option>东莞</option>
                                                <option>印度</option>
                                                <option>宜宾</option>
                                                <option>武汉</option>
                                                <option>宜宾</option>
                                            </select>
                                        </div>


                                        <div class="progress progress-striped active"
                                            style="display: none">
                                            <div id="progressBar"
                                                class="progress-bar progress-bar-success" role="progressbar"
                                                aria-valuemin="0" aria-valuenow="0" aria-valuemax="100"
                                                style="width: 0%"></div>
                                        </div>


                                        <div class="form-group">
                                            <button id="batchUploadBtn" type="submit" class="btn btn-primary">上传文件</button>
                                            <label id="showInfo"></label>
                                        </div>
                                        <div class="form-group">
                                            <img id="imageUpload" alt="上传的后数据" src="" width="100%" />
                                        </div>


                                    </form>
                                </div>
                            </div>
                            <!-- /.row (nested) -->
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
        </div>
        <!-- /#page-wrapper -->
    </div>
    <!-- /#wrapper -->
    <div id="wrapper">
        <div id="page-wrapper">
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">推送历史信息</h1>
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">推送历史记录</div>
                        <div class="panel-body">
                            <div id="">
                                <table id="showPushInfo" class="table table-striped table-hover ">
                                
                                </table>
                            </div>
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
        </div>
        <!-- /#page-wrapper -->
    </div>
    <!-- /#wrapper -->

</body>


<script type="text/javascript">
    /* <![CDATA[> */
    $(document)
            .ready(
                    function() {
                        $("#batchImportBtn").click(function() {
                            $(#batchImportModal).modal(show);
                        });
                        var base = $("#base").val();
                        base = ‘‘;
                        showPushMsgInfo();
                        // 上传按钮
                        $("#batchUploadBtn").attr(disabled, true);
                        $("#showFieInfo").attr(disabled, true);
                        $("#showInfo").text(‘‘);
                        // 上传文件按钮点击的时候
                        $("#batchUploadBtn").click(function() {
                            // 进度条归零
                            $("#progressBar").width("0%");
                            // 上传按钮禁用
                            $(this).attr(disabled, true);
                            // 进度条显示
                            $("#progressBar").parent().show();
                            $("#progressBar").parent().addClass("active");
                            // 上传文件
                            UpladFile();
                        })

                        // 文件修改时
                        $("#batchFile")
                                .change(
                                        function() {
                                            $("#batchUploadBtn").text(
                                                    "数据文件已存在,请推送");
                                            var processbar = $("#progressBar");
                                            processbar.width("0%")
                                            processbar.text(‘‘);
                                            $("#showInfo").text(‘‘);
                                            var file = $(this).prop(files);
                                            if (file.length != 0) {
                                                $("#batchUploadBtn").attr(
                                                        disabled, false);
                                            }
                                            var fileObj = $("#batchFile")
                                                    .get(0).files[0]; // js 获取文件对象
                                            if (fileObj) {
                                                var fileSize = 0;
                                                if (fileObj.size > 1024 * 1024) {
                                                    fileSize = (Math
                                                            .round(fileObj.size
                                                                    / (1024 * 1024)))
                                                            .toString()
                                                            + MB;
                                                } else {
                                                    fileSize = (Math
                                                            .round(fileObj.size / 1024))
                                                            .toString()
                                                            + KB;
                                                }
                                                console.log(fileObj.size)
                                                $("#upfileName").text(
                                                        文件名: + fileObj.name);
                                                $("#upfileSize").text(
                                                        文件大小: + fileSize);
                                                $("#upfileType").text(
                                                        文件类型: + fileObj.type);
                                                $("#showFieInfo").attr(
                                                        disabled, false);
                                            }

                                        });

                        function UpladFile() {
                            var fileObj = $("#batchFile").get(0).files[0]; // js 获取文件对象
                            console.log("上传的文件:" + fileObj);
                            var FileController = base + "/upload"; // 接收上传文件的后台地址 
                            // FormData 对象
                            var form = new FormData();
                            // form.append("author", "hooyes"); // 可以增加表单数据
                            form.append("file", fileObj); // 文件对象
                            // XMLHttpRequest 对象
                            var xhr = new XMLHttpRequest();
                            xhr.open("post", FileController, true);
                            xhr.onload = function() {
                                // ShowSuccess("上传完成");
                                //alert("上传完成");
                                $("#batchUploadBtn").attr(disabled, false);
                                //$("#batchUploadBtn").text("上传");
                                $("#progressBar").parent().removeClass("active");
                                //$("#progressBar").parent().hide();
                                $("#batchUploadBtn").text("文件推送")
                                //$(‘#myModal‘).modal(‘hide‘);
                            };
                            xhr.upload.addEventListener("progress",
                                    progressFunction, false);
                            xhr.addEventListener("load", uploadComplete, false);
                            xhr.addEventListener("error", uploadFailed, false);
                            xhr
                                    .addEventListener("abort", uploadCanceled,
                                            false);
                            xhr.send(form);
                        }
                        function progressFunction(evt) {
                            var progressBar = $("#progressBar");
                            if (evt.lengthComputable) {
                                var completePercent = Math.round(evt.loaded
                                        / evt.total * 100)
                                        + "%";
                                progressBar.width(completePercent);
                                progressBar.text(completePercent);
                                $("#batchUploadBtn").text(
                                        "文件推送中 " + completePercent);
                            }
                        }
                        function formatDate(now) 
                        {
                              var year = now.getFullYear();
                              var month = now.getMonth() + 1;
                              var date = now.getDate();
                              var hour = now.getHours();
                              var minute = now.getMinutes();
                              var second = now.getSeconds();
                               var mill = now.getMilliseconds();
                              return year + "-" + month + "-" + date + "  " + hour + ":" + minute + ":" + second+":"+mill;
                        }
                        function showPushMsgInfo()
                        {
                            var $table = $("#showPushInfo");
                            $.ajax({
                                url : "/showPushInfo",
                                type : "get",
                                async : true,
                                success : function(result) 
                                {
                                    $table.html("");
                                    $.each(result,function(index,item){
                                        console.log(index)
                                        var $tr = $(<tr>);
                                        $.each(item,function(name,val){
                                            if(name==generateTime)
                                            {
                                                val=formatDate(new Date(val));
                                            }
                                            var $td = $(<td>).html(val);
                                            $tr.append($td);
                                        });
                                        $table.append($tr);
                                    });
                                    //$("#showPushInfo").text(JSON.stringify(result))
                                },
                                error : function(result) {
                                    $("#showInfo").text(获取推送信息产生异常:+JSON.stringify(result));
                                }
                            });
                        }
                        function uploadComplete(evt) 
                        {
                            $("#showInfo").text(evt.target.responseText);
                            showPushMsgInfo();
                        }

                        function uploadFailed(evt)
                        {
                            $("#showInfo").text("上传失败,上传文件发生了错误:"+evt.target.responseText);
                        }

                        function uploadCanceled(evt) 
                        {
                            $("#showInfo").text("上传取消,上传被用户取消或者浏览器断开连接:"+evt.target.responseText);
                        }
                    });

    /*]]>*/
</script>
</html>

 

以上是关于springboot带有进度条的上传的主要内容,如果未能解决你的问题,请参考以下文章

带有进度条的 jQuery ajax 上传 - 没有 flash

Flutter 上传带有进度条的大文件。 App 和 Web 都支持

使用 HTML5 和 Javascript 录制/上传带有进度条的固定长度视频

简单的跨浏览器,带有进度条的 jQuery/PHP 文件上传 [关闭]

带进度条的文件上传?

使用 Util.copyStream 的带有进度条的 FTP - JAVA