spring - 为什么 Range 标头不适用于使用嵌入式 Tomcat 从 Spring Boot WAR 托管的静态资源?
问题描述
我有一个使用带有嵌入式 Tomcat 8.5 的 WebMVC 的 Spring Boot 2.0 WAR,并且我在 WAR 中托管我的静态资源。
Range: bytes=0-
对包含HTTP 416(范围不可满足)的静态资源的请求失败,而没有Range
标头的相同请求可以正常工作。
仅就上下文而言,所讨论的静态文件是一个.mp4
视频,浏览器使用Range
标头请求该视频,因为该文件被一个video
元素引用。
在调试器中单步执行,我看到原因是HttpRange.toResourceRegion()
无法确定资源的长度。(或者更确切地说,返回的长度是-1
。)原因是由于资源的 URL 不是文件 URL,它会尝试打开到 URLgetContentLength()
的连接并调用连接,并且WarURLConnection
不会覆盖 returnURLConnection
的默认实现-1
。
我想将此称为 Spring 和/或嵌入式 Tomcat 中的错误,但如果是这种情况,我觉得现在其他人会报告它(我找不到任何证据)。我在这里做一些不寻常的事情吗?
或者也许它实际上适用于其他所有人?也许我错过了一些神奇的 Spring 配置?(我怀疑这与 Spring Boot 的自动配置有关,但我应该在这里提一下,因为我正在将非 Boot 应用程序迁移到 Boot,所以我现在已经禁用了大部分功能。)
我意识到我可以通过“手动”处理这个资源请求(并Resource
在必要时使用自定义实现)来解决这个问题,但似乎我不应该这样做。这似乎应该开箱即用。
解决方案
我相信我已经想通了。事实证明,我所做的事情可能与大多数人的做法略有不同,并且(我认为)Spring Boot 中的一个错误在这种情况下会表现出来。
具体来说,我从 WAR 中托管这些资源,而不是从类路径中托管,因为 Spring Boot 这些天似乎鼓励。在我看来,无法确定war:
URL 的内容长度这一事实是 Spring Boot 和/或嵌入式 Tomcat 中的一个错误。
修复只是将视频资源从src/main/webapp/videos/
to移动src/main/resources/static/videos/
并相应地更新我的资源处理程序注册表配置(例如addResourceLocations("/videos/")
become addResourceLocations("classpath:/static/videos/")
)。
我计划使用 Spring Boot 提交错误报告,当我这样做时我会链接到这里。
编辑:这是错误报告。
推荐阅读
- maven - 我在哪里可以找到使用 JitPack 的 GitHub 版本的正确版本号?
- reactjs - 为子目录强制重定向到 HTTPS
- xml - 需要将label属性带入title
- node.js - 在 Microsoft BotFramework v4 node.js 中使用 Luis 连接对话框
- laravel - Laravel 5.8 带密码重置的电子邮件验证
- scala - 将 Spark 数据帧转换为类似格式的 scala 字典
- spring-hateoas - 为什么 user.get() 方法给我错误?和 idk 如何谷歌
- python - 熊猫数据透视表上的数学计算
- powershell - 我需要在 PowerCLI 中显示一个值及其源主机的名称
- spring-boot - Spring Boot:如何根据配置文件更改注释的值?