SpringBoot 在线预览 切片下载

当我们在进行大文件断点下载、在线音视频预览时,我们不希望从头接收文件数据内容,这时候就用到了文件切片传输的功能。

目录

切片下载原理

如何让服务器识别到一个切片传输请求

示范在Java后端服务器中识别切片请求

服务端如何定位到客户端指定的字节头部

将文件内容写到响应体

告知客户端当前处于切片状态

返回文件的类型格式

注意

感谢


切片下载原理

客户端向服务器提交想要获得的文件段(切片)

服务器识别请求头,理解客户端想要获得的文件段

服务器在将文件内容以流的形式发送给客户端时,通过请求头切片信息(range)来指定读取文件的位置。例如直接读取文件的中间内容。然后将这部分内容写入响应体中。

如何让服务器识别到一个切片传输请求

Range 请求头

例如:bytes=0-

告诉服务器,从0字节一直向后请求资源

当浏览器识别到是一个视频文件资源时,就会自动添加分片的请求头。让我们拖动视频的进度条看看。

可以发现请求的字节从视频文件的中间部分开始了

示范在Java后端服务器中识别切片请求

基于Spring MVC、 SpringBoot v2.3.9.RELEASE

在Controller中,我们可以在请求中获取到HttpServletRequest、HttpServletResponse 对象

调用request对象中的getHeader方法获取range请求头

String range = request.getHeader("Range");

如果客户端进行分片,则range不为null

range的格式有三种

  • 限制头部 例如(bytes=884736-)
  • 限制尾部 (bytes=-123456)
  • 分段截取 (bytes=123456-884736)

使用Chrome自带的视频播放器,使用的是限制头部

 

服务端如何定位到客户端指定的字节头部

找到客户端要请求的文件资源,并使用RandomAccessFile 只读打开文件

使用RandomAccessFile中的seek方法移动文件读取指针,移动至客户端想要读取的起始字节处(range的首个数值)

将文件内容写到响应体

通过response对象中的getOutputStream()方法,获取到输出流。借助BufferedOutputStream和缓冲区byte数组将文件内容写入流。中途不断记录写入的字节数量,直到写到客户端想要的最大字节数处。

告知客户端当前处于切片状态

response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

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

状态代码(206),指示服务器已完成资源的部分GET请求。

返回文件的类型格式

//文件类型

String contentType = request.getServletContext().getMimeType(fileName);

response.setContentType(contentType);

如果浏览器(如Chrome)收到响应,且响应内容为video/mp4或audio/mpeg等能在线播放的格式时,就会以预览的方式打开!否则会启用下载模式下载

 

注意

切片模式可能会导致文件资源无法下载

当我们直接通过浏览器的get请求去下载一个zip压缩包,压缩包的格式是不能够在线预览的,所以浏览器会去下载。

例如我准备下载一个压缩包

但问题发生了

浏览器提示没有发现文件!

但切换到Safari浏览器使用get下载却能够找到文件

经过了两小时代码的调试与问题排查,找到了原因。

不支持切片的文件,服务端不能返回206状态码给客户端

因此需要进行判断,对不进行预览的文件不返回206 ,而返回200即可正常下载!

 

 

感谢

非常感谢Java劝退师、提供的代码参考

SpringBoot SpringMVC文件下载,大文件断点续传,可以实时播放视频,拖动进度条_Java劝退师、的博客-CSDN博客_springboot大文件断点下载

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值