【问题标题】:How to call Java object from CDI bean如何从 CDI bean 调用 Java 对象
【发布时间】:2013-01-18 11:12:36
【问题描述】:

我有一个带有 Java 对象的 CDI bean,我用它来显示来自数据库的配置文件数据:

父 Bean

@Named("DCProfileTabGeneralController")
@ViewScoped
public class DCProfileTabGeneral implements Serializable
{

    public DCObj dc;

    public class DCObj
    {

        private int componentStatsId;                 // COMPONENTSTATSID   NUMBER(38,0)
        ........
        // Default Constructor
        public DCObj(){};

        public DCObj(int componentStatsId....)
        {

            this.componentStatsId = componentStatsId;
            .......

        }

        public int getComponentStatsId()
        {
            return componentStatsId;
        }

        public void setComponentStatsId(int componentStatsId)
        {
            this.componentStatsId = componentStatsId;
        }
        ....
    }

    // Getters ------------------------------------------------------------------------------------
    public DCObj getdcData()
    {
        return dc;
    }

    @PostConstruct
    public void initData() throws SQLException
    {
        initDBData();
    }

    // Generate data Object from Oracle
    public void initDBData() throws SQLException
    {
                dc = new DCObj(result.getInt("COMPONENTSTATSID"),
                .........
    }
}

验证器

@Named("ValidatorDatacenterController")
@ViewScoped
public class ValidatorDatacenter implements Validator, Serializable
{

    public ValidatorDatacenter()
    {
    }

    @Inject
    private DCProfileTabGeneral profileTabGeneral;


    // Validate Datacenter Name
    public void validateDatacenterName(FacesContext context, UIComponent component, Object value) throws ValidatorException, SQLException
    {
        int componentStatsId = -1;

        if (profileTabGeneral != null)
        {
            DCObj dcData = profileTabGeneral.dc;
            if (dcData != null)
            {
                componentStatsId = dcData.getComponentStatsId();
            }
        }

        if (componentStatsId == -1)
        {
            return;
        }

        String l;
        String s;

        if (value != null && !(s = value.toString().trim()).isEmpty())
        {

            if (s.length() > 18)
            {
                throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "  Value is too long! (18 digits max)", null));
            }

            if (ds == null)
            {
                throw new SQLException("Can't get data source");
            }

            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs;
            int resComponentStatsId = -1;
            try
            {
                conn = ds.getConnection();
                // if componentsstatsid <> edited componentstatsid in jsf -> throw validator exception
                ps = conn.prepareStatement("SELECT componentstatsid from COMPONENTSTATS where NAME = ?");
                ps.setString(1, s);
                rs = ps.executeQuery();

                while (rs.next())
                {
                    resComponentStatsId = rs.getInt(1);
                }

                if (resComponentStatsId != -1 && resComponentStatsId != componentStatsId)
                {
                    throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                            "  '" + s + "' is already in use!", null));
                }

            }
            catch (SQLException x)
            {
                throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "  SQL error!", null));
            }
            finally
            {
                if (ps != null)
                {
                    ps.close();
                }
                if (conn != null)
                {
                    conn.close();
                }
            }
        }
        else
        {
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                  "  This field cannot be empty!", null));
        }

    }

}

我有一个自定义验证器,它可以将配置文件页面中的输入值检查到数据库中。我测试了使用@Inject 从父页面获取Java 对象并将Ojject 传递给验证器。事实证明,每次使用 @Inject 时都会得到空的 Java 对象。

我还测试了使用 CDI 获取 Int。它可以工作,但是当我再次测试以再次获取 Java 对象时,我得到了空对象。

你能告诉我从 CDI bean 调用 Java 对象的正确方法是什么吗?为什么我无法从 CDI bean 中获取 Java 对象?

【问题讨论】:

    标签: java jsf jsf-2 cdi


    【解决方案1】:

    如果我没记错的话,CDI 注入将无法与验证器一起使用。使用来自 Myfaces CODI 的高级,因为来自 deltaspike 的 JSF 模块尚未准备好。 https://cwiki.apache.org/EXTCDI/jsf-usage.html

    或者使用 deltaspike 并使用 BeanProvider 来获取您的实例。

    BeanProvider.getContextualReference(DCProfileTabGeneral .class, false);
    

    【讨论】:

    • 我测试了手动将数据插入 Java 对象:private int componentStatsId = 100 并且它可以工作,该值是使用 CDI 传递的。我不明白为什么我不能用数据库中的数据填充 Java 对象。我总是得到空对象。就我而言,我没有标准的 JSF 验证器。我有一个用于验证器的 CDI bean。
    • 看看为什么数据总是空的:两个 CDI bean 都有 ViewScope。但是当我用值对对象进行硬编码时,我得到了正确的数据。事实证明,我从 JSF 页面显示了一个实例,并从验证器加载了一个实例。我想相同的代码被加载了两次,但数据是隔离的。有没有办法将对象共享到一个用户会话中?
    • @Peter Penzov 从 facelet 调用 validateDatacenterName 将不起作用,即使您的 bean 如我在帖子中解释的那样命名。 JSF 2 在 Java EE 6 中完成较早,CDI 完成较晚,集成并不完美。另一个注意事项,尝试使用 SessionScoped,因为 ViewScoped 是 JSF 范围(除非您使用 myfaces CODI)。如果 sessionScoped 对您有用,请将其替换为 ConversationScoped(如果需要)或 CODI 提供的多个范围之一。
    • @PeterPenzov 欢迎您。我必须向您推荐 deltaspike 解决方案,因为任何规模的 CDI 项目都会从中受益。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 2015-07-29
    • 2015-11-03
    • 1970-01-01
    • 2020-02-13
    • 2015-04-20
    • 2012-05-06
    相关资源
    最近更新 更多