Scala Play框架中如何在Filter中间件获取响应头?
问题原因及解决方案
核心问题:Filter执行顺序导致无法获取最终响应头
Play框架的Filter链遵循请求顺次执行,响应逆序执行的规则:
- 请求到达时,会按照你在
DefaultHttpFilters中定义的顺序依次经过每个Filter,最后到达控制器 - 响应返回时,会按照相反的顺序经过每个Filter,最后发送给浏览器
你的CustomFilter被放在了Filter序列的最后一位,这意味着:
响应返回时,CustomFilter会最先处理结果,但后续还有gzipFilter、headFilter、dateFilter、corsFilter等Filter会添加或修改响应头(比如你日志里看到的Access-Control-Allow-Origin、ETag)。因此你在CustomFilter中拿到的result还没经过这些后续Filter的处理,自然看不到最终的响应头。
解决方案:调整CustomFilter的位置到序列最前面
把CustomFilter移到DefaultHttpFilters的第一个位置,这样响应返回时它会最后处理结果,此时所有其他Filter已经完成了响应头的添加和修改,你就能拿到最终发送给浏览器的响应头了。
修改后的Filters类代码:
class Filters @Inject()(corsFilter: CORSFilter, clientIdFilter: ClientIdFilter, requestIdFilter: RequestIdFilter, processingTimeFilter: ProcessingTimeFilter, host: HostFilter, date: DateFilter, head: HeadFilter, gzipFilter: GzipFilter, customFilter: CustomFilter ) extends DefaultHttpFilters(Seq(customFilter, corsFilter, processingTimeFilter, clientIdFilter, requestIdFilter, host, date, head, gzipFilter):_*)
补充说明
你能成功设置新响应头(比如X-Request-ID-022)的原因是:你在CustomFilter中添加的头会被后续的Filter保留(除非被显式修改),最终会被发送到浏览器;但读取操作是在后续Filter处理之前执行的,所以看不到它们添加的头。
内容的提问来源于stack exchange,提问作者Shivam Sahil
相关产品推荐
相关产品推荐

