为何通过Dispatcher访问时SlingHttpServletRequest获取属性返回null?
问题原因与解决方案
核心原因
这是Dispatcher的页面缓存机制导致的:
- 通过Dispatcher访问页面时,若页面已被缓存,Dispatcher会直接返回预存的静态内容,不会将请求转发到Publish节点。你的Sling Filter根本没机会执行,自然
foo属性没被设置,模型里调用request.getAttribute("foo")就返回null。 - 直接访问Publish节点时,请求会走完整的Sling处理流程,Filter正常执行并设置属性,所以能正确获取值。
解决方案
1. 禁用目标页面的Dispatcher缓存
如果页面需要动态生成这个属性值,不让Dispatcher缓存它:
- 在CQ页面的属性中配置
Cache-Control响应头,比如设置为no-cache, no-store,强制每次请求都走Publish节点; - 或者在Dispatcher配置文件(如
dispatcher.any)中,给该页面路径添加缓存拒绝规则:/cache { /rules { /0001 { /type "deny" /url "/content/your-site/your-page.html" } } }
2. 用ESI/SSI拆分动态内容
如果页面大部分内容可以缓存,只有包含该属性的组件是动态的:
- 将动态组件单独封装,在页面模板中使用ESI标签引用它,比如:
<esi:include src="/content/your-site/your-component.html" /> - 配置Dispatcher允许ESI解析,同时确保动态组件的路径不被缓存。这样页面主体被缓存,动态组件的请求会触发Publish的Filter执行,属性能正常设置和获取。
3. 辅助检查Filter配置
虽然直接访问Publish正常,但可以再确认Filter的有效性:
- 检查Filter的
sling.filter.pattern配置,确保包含了页面的访问路径; - 确认Filter的
service.ranking值足够高,保证它在其他相关Filter之前执行。
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

