编写下载服务器。 第三部分:标头:内容长度和范围

这次,我们将探索更多的HTTP请求和响应标头,以改善下载服务器的实现: Content-lengthRange 。 前者表示下载量很大,后者允许部分下载文件或在我们开始时失败后继续下载。

Content-length响应标头对于跟踪下载进度的客户端非常有用。 如果您在甚至开始流传输字节之前就提前发送了预期的资源大小,则Web浏览器之类的客户端可以显示非常准确的进度条,甚至可以通过测量平均下载速度来估计总下载时间。 如果没有Content-length客户端,则客户端将一直保持下载尽可能长的时间,希望流结束一天。 但是,在某些情况下很难获得准确的内容长度。 例如,也许您从其他下载服务器流式传输资源,或者您的资源被即时压缩并直接发送到Servlet响应。 在这两种情况下,您能做的最好的事情就是实际上将数据本地缓存在磁盘上,弄清楚大小是多少,并在数据可用时开始流式传输。 这与始终流式传输,永远不要完全保留在内存中的建议并不矛盾。 在这种情况下,我们将临时文件存储在磁盘上,但在完全准备好并且知道其大小后仍将流式传输。

从Java的角度来看,提供内容长度非常简单:

private ResponseEntity<Resource> response(FilePointer filePointer, HttpStatus status, Resource body) {return ResponseEntity.status(status).eTag(filePointer.getEtag()).contentLength(filePointer.getSize()).lastModified(filePointer.getLastModified().toEpochMilli()).body(body);
}

请注意,还存在Resource.contentLength()方法,但是不同类型的资源对它的计算方式有所不同,有时会急于读取整个资源。 我有自己的FilePointer抽象,知道我们要下载的文件大小。

Range标头是RFC 7233中很好描述的HTTP / 1.1的“新”功能。 这个想法是客户端可以仅请求一部分资源(就字节范围而言),主要有两个原因:

  • 先前的下载已中断,我们不想重复相同的工作。 在这种情况下,客户端知道收到了多少字节并要求剩余部分
  • 我们正在流式传输数据(例如视频),我们想跳过某些部分。 考虑一下像Youtube这样的在线播放器,然后点击进度条中间的。 客户可以简单地估计它现在需要的文件部分,与电影持续时间成比例。

并非所有服务器都需要实现Range请求,因此需要进行一些协商。 第一个客户端发送一个请求,仅请求文件的一部分,在此示例中为前100个字节:

> GET /big_buck_bunny_1080p_surround.avi HTTP/1.1
> Range: bytes=0-99
...

如果目标服务器支持范围请求,则响应206 Partial Content

< HTTP/1.1 206 Partial Content
< Last-Modified: Tue, 06 May 2008 11:21:35 GMT
< ETag: "8000089-375a6422-44c8e0d0f0dc0"
< Accept-Ranges: bytes
< Content-Length: 100
< Content-Range: bytes 0-99/928670754

这里有很多有趣的标题。 首先是206,而不是通常的200 OK。 如果为200 OK,则客户端必须假定服务器不支持范围请求。 示例服务器的运行情况非常好,它还会向我们发送Last-ModifiedETag标头,以改善缓存。 另外,服务器通过发送Accept-Ranges标头确认其能够处理Range请求。 当前仅广泛使用bytes ,但是RFC将来允许其他范围单位(秒?帧?)最后两个标头是最有趣的。 Content-Length不再声明资源的总大小,而是我们请求的范围的大小,在这种情况下为100字节。 完整资源的大小以Content-Range编码: bytes 0-99/928670754 。 就我们收到的内容而言,服务器非常精确:前100个字节( 0-99 ),而总资源大小为928670754 。 知道客户端的总大小后,基本上可以请求多个文件中的文件部分。

Range请求的规范具有很大的灵活性,例如我们可以在一个请求中请求多个范围,例如:

> GET /big_buck_bunny_1080p_surround.avi HTTP/1.1
> Range: bytes=0-9,1000-1009
...
< HTTP/1.1 206 Partial Content
< Accept-Ranges: bytes
< Content-Type: multipart/byteranges; boundary=5187ab27335732
<--5187ab27335732
Content-type: video/x-msvideo
Content-range: bytes 0-9/928670754[data]
--5187ab27335732
Content-type: video/x-msvideo
Content-range: bytes 1000-1009/928670754[data]
--5187ab27335732--

但是,服务器可以自由地优化多个范围请求,例如重新布置它们,合并等。从头开始实现部分请求超出了本文的范围,我希望您不必自己做。 例如,从4.2.x开始的Spring对静态资源的部分请求具有全面的内置支持,请参阅: ResourceHttpRequestHandler第463行 。

编写下载服务器

  • 第一部分:始终流式传输,永远不要完全保留在内存中
  • 第二部分:标头:Last-Modified,ETag和If-None-Match
  • 第三部分:标头:内容长度和范围
  • 第四部分:有效地实现HEAD操作
  • 第五部分:油门下载速度
  • 第六部分:描述您发送的内容(内容类型等)
  • 这些文章中开发的示例应用程序可在GitHub上找到。

翻译自: https://www.javacodegeeks.com/2015/07/writing-a-download-server-part-iii-headers-content-length-and-range.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dede文章列表加上序号效果

dede文章列表加上序号效果 css代码部分 <style type"text/css"> <!-- .downtop { FLOAT: left; OVERFLOW: hidden; WIDTH: 218px; HEIGHT: 278px } .downtop UL.text { MARGIN: 0px 10px; WIDTH: 198px; PADDING-TOP: 5px } .downtop UL.text LI { WIDTH: 1…

解答互联网创业中,你肯定会遇到的问题!

作为创过业&#xff0c;并且失败了的人&#xff0c;还是有那么一点点经验来回答这些问题的。1.我现在有个idea&#xff0c;上线之前如何在保证不被泄露的情况下又能了解这个idea对用户有多大吸引力&#xff1f;答&#xff1a;短时间内快速做出原型&#xff0c;找到10个左右的目…

android 垂直自动滚动条,Android实现Activity水平和垂直滚动条的方法

本文实例讲述了Android实现Activity水平和垂直滚动条的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;android:layout_width"match_parent"android:layout_height"match_parent"android:scrollbars"vertical" >android:layout_…

javadoc定义异常_Doclava:来自Google的自定义Javadoc Doclet

javadoc定义异常Doclava是Google的自定义Javadoc Doclet&#xff0c;由Google Guice使用&#xff08;请参见稍冷一些的Javadocs &#xff09;。 Doclava使用JSilver作为其模板引擎&#xff0c;这是Clearsilver的纯Java实现。 我个人喜欢联合文档的想法&#xff0c;该概念允许文…

HDU 2845 Beans

本来是很简单的一道题&#xff0c;却想了好长时间 由于数据量比较大&#xff0c;所以逐行读入&#xff0c;逐行处理 先处理每一行的不相邻元素和的最大值&#xff0c;记录在数组b中 最后计算不相邻行的和的最大值 二者的状态转移方程都类似&#xff1a;dp[j] max(dp[j - 1], d…

计算机由什么组成

对于一个不是计算机专业的编程人员&#xff0c;有很多东西要去学习&#xff0c;一直不理解计算机的组成和原理&#xff0c;今天查看百科&#xff0c;稍微了解一下写出来&#xff0c;让以后巩固&#xff1a; 1&#xff0c;计算机是由硬件系统和软件系统组成的 硬件系统&#xff…

android 重新启动应用程序,通过单击应用程序图标打开Android应用程序时重新启动...

我是Android开发世界的新手,我已经建立了一个简单的“Hello World”应用程序.首先,活动请求一个文本.当单击“Go”按钮时,应用程序将启动显示输入文本的第二个活动.如果我单击HOME按钮,然后单击应用程序图标,该应用程序将再次启动第一个活动,但是如果我按住主屏幕按钮并单击“最…

继承,is,as,多态

继承中的构造方法&#xff1a;1、创建子类对象时&#xff0c;一定会先创建父类对象2、如果调用的子类构造方法没有使用base&#xff0c;就会自动调用父类无参的构造方法&#xff0c; 如果父类没有无参的构造方法就会报错3、如果调用的子类构造方法使用了base&#xff0c;就会…

太古鸿蒙诀正式版v1.07,百变队长安崎:台上小辣椒,台下情歌王

在舞台上魅力四射的THE9队长安崎&#xff0c;在台下却是喜欢唱情歌的软萌girl。这样的安崎你爱了么&#xff1f;反差萌王者安崎作为队长&#xff0c;在舞台上的表现一直都是“炸裂”、“辣”、“性感”、“野性”&#xff0c;而舞台之下的安崎则一直呈现的是可爱、甜美&#xf…

erlang 架构原理_Erlang与Java内存架构

erlang 架构原理我读了一篇关于Erlang VM的内存管理策略的非常非常有趣的文章。 它是Jesper Wilhelmsson撰写的论文 &#xff0c;我认为讨论Erlang的内存设置和Oracle的Java VM之间的差异可能会很好。 作为对从未听说过Erlang的人们的一个简短的介绍; 它是一种功能语言&#xf…

ASP.NET MVC IOC 之AutoFac攻略

一、为什么使用AutoFac&#xff1f; 之前介绍了Unity和Ninject两个IOC容器&#xff0c;但是发现园子里用AutoFac的貌似更为普遍&#xff0c;于是捯饬了两天&#xff0c;发现这个东东确实是个高大上的IOC容器~ Autofac是.NET领域最为流行的IOC框架之一&#xff0c;传说是速度最快…

android对话框跳转页面,android应用Dialog跳转到Activity

Java基础-四要素之一《多态》什么是多态 指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同的行为方式.(发送消息就是函数调用) 多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的 ...java进制转换器 图形用户界面 十进…

apache cxf_Apache CXF负载平衡和故障转移

apache cxf不久前&#xff0c;我们已经面临了基于Apache CXF的负载平衡Web服务客户端的需求。 此外&#xff0c;当某些服务器关闭时&#xff0c;客户端应自动进行故障转移。 更糟糕的是&#xff0c;服务器目标地址列表要从外部服务获取并在运行时更新。 最终&#xff0c;我们最…

HDU 1874 最直接的最短路径问题

题目链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1874 Problem Description某省自从实行了很多年的畅通工程计划后&#xff0c;终于修建了很多路。不过路多了也不好&#xff0c;每次要从一个城镇到另一个城镇时&#xff0c;都有许多种道路方案可以选择&#xf…

晶体管

晶体管-沟道 场效应-电容性的控制沟道 势效应-直接控制沟道 平带电压 由于半导体和金属的功函数的不同&#xff0c;导致半导体表面层并不属于平带状态&#xff0c;为了恢复平带状态所加的电压为平带电压&#xff0c;Vfb 转载于:https://www.cnblogs.com/rice808/p/3874597.html…

领域驱动设计模式设计与实践_在域驱动设计中使用状态模式

领域驱动设计模式设计与实践域驱动设计&#xff08;DDD&#xff09;是一种开发软件的方法&#xff0c;其中&#xff0c;通过将实现与核心业务概念的不断发展的模型相联系&#xff0c;解决了问题的复杂性。 该术语是由Eric Evans创造的&#xff0c;并且有一个DDD专用站点可以促进…

html 英文文字纵向排列,CSS几种简单方法实现文字竖向排版

1.一个句子的竖向排列如图&#xff1a;1.2. test.one {width: 20px;margin: 0 auto;line-height: 24px;font-size: 20px;}.two {width: 15px;margin: 0 auto;line-height: 24px;font-size: 20px;word-wrap: break-word;/*英文的时候需要加上这句&#xff0c;自动换行*/}我是竖列…

jstree 节点拖拽保存数据库

需要jstree具有拖拽功能需要在加载jstree时添加dnd插件&#xff0c;具体看代码&#xff1a; $(**).jstree({//plugins-各种jstree的插件引入&#xff0c;展示树的多样性 plugins : [ "dnd", "types", "wholerow" ], core : {"check_callbac…

html js utf8编码转换,js 编码转换 gb2312 和 utf8 互转的2种方法

方法一:function gb2utf8(data){var glbEncode [];gb2utf8_data data;execScript("gb2utf8_data MidB(gb2utf8_data, 1)", "VBScript");var tescape(gb2utf8_data).replace(/%u/g,"").replace(/(.{2})(.{2})/g,"%$2%$1").replace(/…

向其他进程注入代码的三种方法

如何向其他线程的地址空间中注入代码并在这个线程的上下文中执行之&#xff1f; 目录&#xff1a;●导言●Windows 钩子&#xff08;Hooks&#xff09;●CreateRemoteThread 和LoadLibrary 技术○进程间通讯●CreateRemoteThread 和 WriteProcessmemory 技术○如何使用该技术子…