使用 CDI(上下文和依赖注入)支持 Bean 代替托管 Bean

发布于 2024-11-18 07:10:42 字数 2262 浏览 1 评论 0原文

我认为建议使用 CDI bean 作为支持 bean,而不是 JSF 托管 bean。

所以我决定创建一个小例子,以了解它是如何工作的,对于 @RequestScopedBean

-而不是使用 @ManagedBean("beanName") ,我使用 >@Named("beanName")

- 我不使用 javax.faces.bean.RequestScopped,而是使用 javax.enterprise.context.RequestScoped;

演示程序很简单,我有一个字段和一个提交按钮,当用户输入内容并且刷新页面时,输入的值不再显示(它在请求持续时持续显示,对吧?)。我认为我做的一切都很好,但我得到一个例外:

警告:StandardWrapperValve[面孔 Servlet]:PWC1406:Servlet.service() 对于 servlet Faces Servlet 抛出 例外 javax.el.PropertyNotFoundException: /index.xhtml @19,47 value="#{cdiBean.passedValue}":目标 无法访问,标识符“cdiBean” 解析为 null

这是我的程序的样子:

index.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">

<h:head>
        <title>RequestScope demo CDI(Component Dependency Injection)</title>
</h:head>

<h:body>

    <h:form>

    <h3>RequestScope demo CDI(Component Dependency Injection)</h3>

    <h:inputText value="#{cdiBean.passedValue}"/>
    <br/>
    <h:commandButton value="submit" action="index"/>

    </h:form>
</h:body>
</html>

DemoBB.java

package backingbeans;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named("cdiBean")//The Named anotation indicates that this is a CDI bean
@RequestScoped//If we use CDI beans the @RequestScoped annotation must come from: javax.enterprise.context.RequestScoped;
public class DemoBB {

    //This value will be saved on the session only until the server responds to the request
    private String passedValue;

    public String getPassedValue() {
        return passedValue;
    }

    public void setPassedValue(String passedValue) {
        this.passedValue = passedValue;
    }   
}

- 我的错误在哪里?

- 使用这种方法有什么好处?我还是不明白。

I rode that is recommended to use CDI beans as backing beans instead of JSF managed beans.

So i decided to create a little example, to understand how it works, for a @RequestScopedBean:

-instead of using @ManagedBean("beanName") ,i use @Named("beanName")

-instead of using javax.faces.bean.RequestScopped i use javax.enterprise.context.RequestScoped;

The demo program is very simple, i have a field and a submit button, when the user inputs something and the page is refreshed, the inputed value is not displayed anymore(It last while the request lasts right?). I think i did everything ok, but i get an exception that says:

WARNING: StandardWrapperValve[Faces
Servlet]: PWC1406: Servlet.service()
for servlet Faces Servlet threw
exception
javax.el.PropertyNotFoundException:
/index.xhtml @19,47
value="#{cdiBean.passedValue}": Target
Unreachable, identifier 'cdiBean'
resolved to null

This is how my program looks like:

index.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">

<h:head>
        <title>RequestScope demo CDI(Component Dependency Injection)</title>
</h:head>

<h:body>

    <h:form>

    <h3>RequestScope demo CDI(Component Dependency Injection)</h3>

    <h:inputText value="#{cdiBean.passedValue}"/>
    <br/>
    <h:commandButton value="submit" action="index"/>

    </h:form>
</h:body>
</html>

DemoBB.java

package backingbeans;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named("cdiBean")//The Named anotation indicates that this is a CDI bean
@RequestScoped//If we use CDI beans the @RequestScoped annotation must come from: javax.enterprise.context.RequestScoped;
public class DemoBB {

    //This value will be saved on the session only until the server responds to the request
    private String passedValue;

    public String getPassedValue() {
        return passedValue;
    }

    public void setPassedValue(String passedValue) {
        this.passedValue = passedValue;
    }   
}

-Where is my mistake?

-What is the advantage of using this approach? I still don't understand that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

假扮的天使 2024-11-25 07:10:42

您的 web.xml 中是否有空的 beans.xml ?我认为去那里是必须的。

请阅读此处第 15.6 节。摘自其中:

CDI 没有定义任何特殊的
部署存档。你可以打包
JAR、EJB-JAR 或 WAR 中的 bean——任何
应用程序中的部署位置
类路径。但是,存档必须
成为“bean 档案”。这意味着每个
包含 beans 的存档必须
包含一个名为 beans.xml 的文件
类路径的 META-INF 目录或
Web 根目录的 WEB-INF 目录(用于
战争档案)。该文件可能为空。
部署在不存在的档案中的 Bean
有 beans.xml 文件就不会
可在应用程序中使用。

在可嵌入的 EJB 容器中,bean
可以部署在任何地点
可以部署哪些 EJB。再次,
每个位置必须包含 beans.xml
文件。

Do you have an empty beans.xml along with your web.xml? I think it is mandatory to be there.

Read section 15.6 here. Quote from it:

CDI doesn't define any special
deployment archive. You can package
beans in JARs, EJB-JARs or WARs—any
deployment location in the application
classpath. However, the archive must
be a "bean archive". That means each
archive that contains beans must
include a file named beans.xml in the
META-INF directory of the classpath or
WEB-INF directory of the web root (for
WAR archives). The file may be empty.
Beans deployed in archives that do not
have a beans.xml file will not be
available for use in the application.

In an embeddable EJB container, beans
may be deployed in any location in
which EJBs may be deployed. Again,
each location must contain a beans.xml
file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文