zoukankan      html  css  js  c++  java
  • Spring 4.3.2下实现http多次断点下载

    其实跟 spring 无关,如果是直接下载资源很多 web sever 不用程序就直接实现了断点。

    但我们的应用是 download?url=xxxx 这种方式 下载资源由 download 来负责,所以得手工改写一下代码。

    断点续传,听上去似乎是个比较高级的话题,我们现在用的是http版的断点续传,其他协议的大家可以自行研究。

    http协议中,服务端实现断点续传首先需要读取客户端传送的Range头信息,比如“Range: bytes=12583394-这个就是指原来正在下载的文件需要从第12583394字节继续下载,然后我们利用java.io.File的skip方法,舍弃掉原文件的前n个字节,接着就继续慢慢write吧。。。

    但是客户端又是如何判断服务端是否支持断点续传的呢?主要就是Accept-Ranges和Content-Length头信息。比如“Accept-Ranges:bytes”和“Content-Length:99999999”。有了这两个头信息,客户端就认为服务端是支持断点续传的了。

    然后需要注意的是,假如客户端刚才由于某些原因,暂停了下载,现在恢复的时候,就会如前所述,传来Range头信息,这时候,我们的response就需要设置一下状态码,这里应该设置成206(详细解释请看http://en.wikipedia.org/wiki/List_of_HTTP_status_codes),还有就是Content-Range头信息,格式为“bytes x-(y-1)/y”,x就是客户端传来的开始字节位置,y就是文件长度。

    理解了这些,再看看给出的实例关键代码:

     1                     response.reset();
     2                     response.setCharacterEncoding("utf-8");
     3                     response.setContentType("application/x-download");
     4                     response.setHeader("Accept-Ranges", "bytes");
     5                     response.setHeader("Content-Length", String.valueOf(fSize));
     6                     response.setHeader("Content-Disposition", "attachment; filename="" + new String(filename.getBytes(guessCharset), "iso-8859-1") + """);
     7                     in = new FileInputStream(file.getPath());
     8 
     9                     long pos = 0;
    10                     if (null != request.getHeader("Range")) {
    11                         // 断点续传
    12                         response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
    13                         try {
    14                             pos = Long.parseLong(request.getHeader("Range").replaceAll("bytes=", "").replaceAll("-", ""));
    15                         } catch (NumberFormatException e) {
    16                             pos = 0;
    17                         }
    18                     }
    19                     out = response.getOutputStream();
    20                     String contentRange = new StringBuffer("bytes ").append(pos + "").append("-").append((fSize - 1) + "").append("/").append(fSize + "").toString();
    21                     response.setHeader("Content-Range", contentRange);
    22                     in.skip(pos);
    23                     byte[] buffer = new byte[1024 * 10];
    24                     int length = 0;
    25                     while ((length = in.read(buffer, 0, buffer.length)) != -1) {
    26                         out.write(buffer, 0, length);
    27                         // Thread.sleep(100);
    28                     }

    再来看一下效果图:

  • 相关阅读:
    leetcode950
    leetcode938
    leetcode953
    推荐系统那点事儿
    极大似然估计的理解与应用
    吴恩达机器学习笔记 —— 1 绪论:初识机器学习
    吴恩达机器学习笔记 —— 3 线性回归回顾
    吴恩达机器学习笔记 —— 5 多变量线性回归
    吴恩达机器学习笔记 —— 7 Logistic回归
    吴恩达机器学习笔记 —— 8 正则化
  • 原文地址:https://www.cnblogs.com/interdrp/p/5923500.html
Copyright © 2011-2022 走看看