这个问题开始出现是因为我读了Arjan Tijms关于JSF 2.3的博文。在这里,他列出了所有可以通过CDI注入的JSF构件。虽然提到了HttpServletRequest
,但HttpServletResponse
并没有出现在上述列表中,这一点我一开始并不相信。
@Inject private HttpServletRequest req;
工作正常@Inject private HttpServletResponse res;
抛出DeploymentException: WELD-001408: Unsatisfied dependencies for type HttpServletResponse
我不明白为什么HttpServletResponse
不应该注射。毕竟,我们的目标是用简洁的注入取代复杂的方法链。在HttpServletRequest
的情况下,FacesContext.getCurrentInstance().getExternalContext().getRequest();
现在可以缩短为上述注入。
在HttpServletResponse
的情况下,没有可以替代FacesContext.getCurrentInstance().getExternalContext().getResponse();
的候选注入,如上图所示。
总结:为什么HttpServletRequest
可以经CDI注射,而HttpServletResponse
不能?
这里没有一个好的答案。
首先,HttpServletRequest
是由CDI产生的,而不是Faces。至于HttpServletResponse
,我不确定为什么它最初不包含在CDI中,但我知道所有的Servlet工件最初不应该由CDI提供。
相反,CDI应该要求Servlet提供"生产者";对于它们(从技术上讲,是内置bean)。Jakarta Transactions(当时的JTA)也做了类似的事情)
目前,CDI并不想增强或扩展Servlet构件,这是有充分理由的。CDI正专注于其核心bean模型和注入。
然而,在Servlet中,对于提供生产者的含义存在着巨大的误解。Servlet中至少有一个人认为这是关于提供集成点,或者关于Servlet必须完全基于CDI,或者关于Jetty必须支持所有10个CDI实现(只有2个,但除此之外)。
这个讨论已经持续了至少8年。问题已经打开并再次关闭。
我自己就是一个Servlet成员,所以我希望我能有一些影响,但仍然没有能够解决这个问题。
我们也可以让Faces提供HttpServletResponse
,但Faces也不拥有该类型,这可能只会导致混乱。
如前所述,CDI默认不支持注入HttpServletResponse
。然而,Apache DeltaSpike的Servlet模块允许注入Servlet对象,比如HttpServletResponse
。因此,不需要编写自定义的CDIProducer
或@Produces
方法来通过CDI注入HttpServletResponse
。