【问题标题】:CDI injection in a JSPJSP 中的 CDI 注入
【发布时间】:2011-11-15 04:33:15
【问题描述】:

在 JSP 中,可以使用 ${myBean.myAttribute} 等 EL 表达式来使用 CDI 托管 bean。这里没问题。

我想在 JSP 文件中使用带有 @Inject 的“常规注入”(即不使用 EL 表达式),例如: 然后是 。即使该示例可以使用 EL 表达式来实现,但其他一些用例却不能。

应用服务器似乎并不完全支持这一点:
- JBoss 6.0.0、JBoss 6.1.0、Resin 4.0.22:好的,它工作得很好。
- JBoss 7.0.1、GlassFish 3.x(测试了多个版本):失败,myBean 仍然为空。

它应该可以在 JSP 中正常工作,因为:
(1) 根据各种相关规范,它在 servlet 中运行良好,并且
(2) JSP 在运行时被翻译成 servlet。

你们知道我正在尝试做的事情是否受支持吗?可能有任何内部/实施信息吗?

【问题讨论】:

  • 我不知道它是否(或应该)支持,但我知道在 JSP 中这样做只是一个坏主意。 JSP 旨在生成标记。多年来,它们不应该包含 Java scriptlet。在常规 servlet 中执行您想要执行的操作,然后分派到 JSP。仅在 JSP 中使用 EL 和 JSP 标签。
  • 使用 servlet 和/或 MVC 框架在某些情况下会有所帮助,具体取决于应用程序的要求。但有时添加一个 servlet 只是为了将服务 bean 引用传递给 JSP 是多余的,并且可能被认为是一种反模式。我真正感兴趣的是了解 JSP 的 CDI 行为,即使有其他解决方案。 :)

标签: jsp jakarta-ee el code-injection cdi


【解决方案1】:

有趣的问题,如果您没有对其进行测试,我会在它不起作用的事实上赌一些钱;-)

CDI 基于托管 bean (JSR 316)。相应的定义相当宽松(故意):

来自规范:

可以通过使用注释来声明托管 Bean javax.annotation.ManagedBean 注释。托管 Bean 不得: final 类,抽象类,非静态内部类。托管 与常规 JavaBean 组件不同,Bean 可能不可序列化。

在基本组件模型中,Managed Beans 必须提供无参数 构造函数,而是建立在托管 Bean 之上的规范,例如 CDI (JSR-299),可以放宽该要求并允许托管 Bean 为构造函数提供更复杂的签名,

可能发生的情况是容器扫描类路径并碰巧找到已编译的 JSP servlet。自从我上次看到一个以来已经有一段时间了,但我记得代码已生成并且所有内容(包括脚本)都位于 doGet()doPost()...!?因此,即使他们在定义方面正式不取消资格,我怀疑 JSP 脚本是否是您想要考虑的托管 bean。老实说,这感觉非常错误;-)

我关注 CDI / Weld / Seam 邮件列表已经有一段时间了,我不记得曾经提到过 JSP。与谷歌搜索此连接相同。

因此,您不应依赖 CDI 来处理 scriptlet。恕我直言,这种行为比有意的行为具有更多的副作用,并且可以在未来的版本中删除,恕不另行通知(或者甚至没有被注意到 :-)

因此,对于 JB Nizet 的提议 +1:使用带有 CDI 的 servlet,而不是 JSP。

更新:我试图提供帮助,而不是制造混乱 ;-) 我的意思是:恕我直言,在 JSP 中使用 CDI 感觉真的很错误,但我在相关规范中没有找到任何内容这证明了这一点。我只能说 JSP 在任何地方从未提及 - 这支持了我的直觉(并且符合某些实现确实考虑它的观察结果,其他实现不考虑它)。

【讨论】:

  • 我不理解您关于“CDI 建立在托管 bean 上”的断言。事实上,CDI makes JSF managed beans not necessary 并且不需要在其托管 bean 中使用 @ManagedBean 注释 - 一个类 just need a default constructor 是一个 bean。此外,Weld 参考声明 servlets are beans 所以我敢打赌 JSP 生成的 servlet 将支持注入(不考虑它的好坏)。
  • 不不,您将 JSF javax.faces.bean.ManagedBean 与 CDI javax.annotation.ManagedBean 混合在一起 - 不幸的模棱两可。 This Weld documentation chapter 是(重新)评估 CDI 的良好开端,请同时检查引用的 JSR 316... 是的,servlet 是 bean,这是毫无疑问的。但老实说,我不知道生成的 servlet 是否适合该方案——就像我之前写的那样。
  • 并非所有 JSP 脚本元素都以 doGet/doPost 结尾,JSP“声明”(即“”内容)定义类属性或方法。这非常适合 @Inject 属性。从这个澄清来看,Jan,我不明白你的逻辑含义以及你为什么说“他们正式不合格”。
【解决方案2】:

我认为 JSP 没有现成可用的可移植 @Inject,但应该可以(在容器级别)以与 servlet 相同的方式实现它。

虽然我同意这不是利用 CDI 的最佳方式,但从技术上讲,我认为没有任何理由反对它。例如,servlet 中的 AFAIK @Inject 透明地使用 ThreadLocal 代理,为什么不在 JSP 中使用此功能?

【讨论】:

    【解决方案3】:

    试试这个:-

    <%!
        @Inject
        private UserService userService;
    %>
    

    它对我有用:)

    注意: 使用括号&lt;%! %&gt;而不是&lt;% %&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-23
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 2017-10-25
      • 2014-06-02
      相关资源
      最近更新 更多