我有一个使用WebMVC和嵌入式Tomcat 8.5的Spring Boot 2.0 WAR,并且在WAR中托管我的静态资源。
对包含Range: bytes=0-
的静态资源的请求因HTTP 416(范围无法满足)而失败,而没有Range
标头的相同请求也可以正常工作。
就上下文而言,所涉及的静态文件是.mp4
视频,浏览器使用Range
标头请求该视频,因为该文件是由video
元素引用的。
逐步进入调试器,我发现原因是HttpRange.toResourceRegion()
无法确定资源的长度。 (或者,返回的长度为-1
。)原因是由于资源的URL不是文件URL,因此它尝试打开与该URL的连接并在该连接上调用getContentLength()
,然后{{ 1}}不会覆盖WarURLConnection
返回URLConnection
的默认实现。
我想称它为Spring和/或嵌入式Tomcat中的错误,但是如果是这种情况,我觉得现在其他人已经报告了它(并且我找不到任何证据)。我在这里做一些不寻常的事情吗?
也许它实际上对其他所有人都有效?也许我错过了一些神奇的Spring配置? (我怀疑这与Spring Boot的自动配置有关,但是我要在这里提到的是,在我将非Boot应用程序迁移到Boot时,我暂时禁用了其中的大部分功能。)
我意识到我可以通过“手动”处理此资源请求(并在必要时使用-1
的自定义实现)来解决此问题,但看来我不必这样做。似乎应该立即使用即可。
答案 0 :(得分:2)
我相信我已经解决了。事实证明,我在做的事情与大多数人可能略有不同,并且(在我看来)Spring Boot中也存在一个错误,这种情况在这种情况下会显现出来。
具体来说,我最近从WAR而不是从类路径托管这些资源,因为Spring Boot似乎鼓励了这些日子。我认为无法确定war:
URL的内容长度,这是Spring Boot和/或嵌入式Tomcat中的错误。
解决方法只是将视频资源从src/main/webapp/videos/
移到src/main/resources/static/videos/
并相应地更新我的资源处理程序注册表配置(例如addResourceLocations("/videos/")
变成了addResourceLocations("classpath:/static/videos/")
)。
我计划通过Spring Boot提交一个错误报告,当我这样做时将链接到这里。
编辑:这里是the bug report。