Home > Java > javaTutorial > body text

JAVA supports HTTP breakpoint resume download

大家讲道理
Release: 2016-11-11 10:41:14
Original
1268 people have browsed it

File downloading is the most basic service provided by WEB websites, but do you know how HTTP resumed downloading is implemented?

Background

In the past two days, I have been implementing an online audio and video playback based on HTML5. Since the file is stored in the corporate network disk and HTTP is not reachable, a program is needed to read the file and download the HTTP protocol.

It goes without saying that using Java to download files is just a matter of reading the file and writing it to the response through a binary stream. The H5 player call can also be played; however, when I control the progress forward and backward, the problem comes, and it has no effect at all! Is it still called a player if there is no fast-forward player?

Analysis

First of all, when we see that the player cannot obtain the time length of the audio and video files, we naturally think of the Content-Length attribute. In the background, we obtain the file length through file.length() and set it to Content-Length (the code is as follows) ), the length of the audio and video can be displayed in the foreground player, and it can be fast forwarded; however, when I rewind, it is still invalid and an error is reported in the background.

response.addHeader("Content-Length", file.length());
Copy after login

I changed an HTTP file for comparison testing and found that direct HTTP access can fast forward and rewind normally. After careful analysis of the request and response headers of the two, I found the difference, the request parameters There are more attributes as shown in the figure below. The attribute table name needs to be the resource range obtained from the server. By default, it starts from the first byte. Fast forward and fast rewind actually determine the starting point you expect by specifying the Range attribute. starting point.

JAVA supports HTTP breakpoint resume download

However, this attribute is in the request header. How does the client know to add this attribute? Continuing to search, I found the Accept-Ranges attribute. The attribute value is bytes, which indicates whether to accept a request to obtain a part of an entity (such as a part of a file). bytes: indicates acceptance, none: indicates not acceptance. There is another attribute in the corresponding response, Content-Range, which indicates which part of the entire object the partial object contained in the response is. The complete response header is as follows:

JAVA supports HTTP breakpoint resume download

Solution

Based on the above analysis, we know how to handle it on the server side. First, add Accept-Ranges to the response header.

response.setHeader("Accept-Ranges", "bytes");
Copy after login

Then determine whether the Range attribute exists in the request, that is, whether the specified starting point exists. If it exists, jump directly to the target starting point through the skip of the stream, and finally add the Content-Range attribute table name of the start and end of the current block, complete code As follows:

stream = new FileInputStream(file);
if(request.getHeader("Range") != null) //客户端请求的下载的文件块的开始字节   
  {
    //从请求中得到开始的字节   
    //请求的格式是:   
    //Range: bytes=[文件块的开始字节]-  
    String range = StringUtils.substringBetween(request.getHeader("Range"), "bytes=", "-");
    long start = Long.parseLong(range);   
    //下载的文件(或块)长度   
    //响应的格式是:   
    //Content-Length: [文件的总大小] - [客户端请求的下载的文件块的开始字节]   
    response.setHeader("Content-Length", String.valueOf(fileSize - start));   
                
    if (start != 0)  
    {
      //要设置状态   
      //响应的格式是:   
      //HTTP/1.1 206 Partial Content  
               response.setStatus(javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT);//206   
      //不是从最开始下载,   
      //响应的格式是:   
      //Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小]   
      response.setHeader("Content-Range","bytes " + start + "-" + String.valueOf(fileSize - 1) + "/" + String.valueOf(fileSize));  
                
      stream.skip(start);
      }
    }
    responseBinaryStream(response, this.getContentType(FilenameUtils.getExtension(fileName)), stream);
Copy after login
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template