【问题标题】:How does EL #{bean.id} call managed bean method bean.getId()EL #{bean.id} 如何调用托管 bean 方法 bean.getId()
【发布时间】:2023-03-27 08:47:01
【问题描述】:

我不太明白 getter 和 setter 是如何工作的,尽管它是一个基本概念。我有以下代码,属性id是如何发送到Managed Bean的?是getter方法捕获的吗?

我的脸

<p:inputText id="id" value="#{bean.id}">

我的托管 bean

private String id;

public void setId(String id) {
    this.id = id;
}

public String getId() {
      return id;
}

【问题讨论】:

标签: jsf el getter


【解决方案1】:

#{} 表达式对 getter 和 setter 方法的调用不是 JSF 的一部分,而是 Expression Language(众所周知的 EL)。 JSF 利用 EL 通过适当的 getter 和 setter 将 HTML 组件的数据绑定到 bean 的字段。这是:

  • 如果 bean 存在,表达式语言将在适当的范围内执行已注册 bean 的适当 getter。
  • 如果客户端执行表单提交或ajax请求,则发送到服务器的组件(通常是&lt;h:form&gt;中的所有组件,如果是ajax请求,您可以说明要发送到服务器的组件)将包含一个新值,并且该值将使用适当的 setter 方法设置到该字段。

例如,您有一个属于请求范围的SayHelloBean

@RequestScoped
@ManagedBean
public class LoginBean {
    private String name;
    //proper getter
    public String getName() {
        return this.name;
    }
    //proper setter
    public void setName(String name) {
        this.name = name;
    }
}

还有这 2 个 facelets 页面(因为这是一个示例,所以我避免声明 &lt;html&gt;&lt;h:head&gt;&lt;h:body&gt; 和其他元素,只关注相关代码)

Page1.xhtml:

<h:form>
    Please tell me your name
    <h:inputText value="#{loginBean.name}" />
    <h:commandButton action="page2" />
</h:form>

Page2.xhtml:

Hello #{loginBean.name}

这就是幕后发生的事情:

  1. 当 Page1.xhtml 被加载时,一个新的 LoginBean 实例,我们可以称之为 loginBean,将由 JSF 创建并注册到 JSP 请求范围中。由于&lt;h:inputText /&gt; 的值绑定到LoginBean#name(读作LoginBean 类的name 字段),那么EL 将显示loginBean#name 的值(即读取为实例loginBean的字段name),并且由于未初始化,EL将显示null,作为一个空字符串。

  2. 当你提交Page1.xhtml的表单时,由于LoginBean@RequestScoped,那么JSF会创建一个LoginBean的新实例,我们可以称之为loginBean2(在最后,因为这个实例与之前创建的loginBean 完全不同)并将其注册到 JSP 请求范围内。由于&lt;h:inputText /&gt; 的值绑定到LoginBean#name,JSF 将通过调用适当的设置器来验证和设置数据。这将使loginBean2#name 具有由&lt;h:inputText/&gt; 呈现的&lt;input type="text"&gt; 的值。

  3. 最后,JSF 将确保通过 forward 导航到 Page2.xhtml,在处理它时,它会找到 #{loginBean.name},EL 会检查 loginBean2#name 的值并替换它。

这里解释的步骤是对 JSF 生命周期以及 JSF 如何使用 getter 和 setter 的非常小的解释(并且有很多元素没有解释)。

更多信息:


附加说明:由于您正在学习 JSF,因此请避免将任何业务逻辑代码放在 getter/setter 中。这在这里得到了很好的解释:Why JSF calls getters multiple times

【讨论】:

  • 很好解释。但是我将如何从数据库中用一个值(设置默认值是另一回事,我不是问这个)初始化一个输入文本(在你的情况下提到)。如果我使用 PostContruct 执行此操作(名称初始化为 someDataBaseValue()),那么它可以正常工作。但我不明白为什么这在构造函数中不起作用。
  • @ShirgillAnsari 虽然我对托管 bean 构造函数进行了一些调试,但我注意到 JSF 根本没有调用它们,但 @PostConstruct 方法会调用它们(在注入元素之后,如果有的话)。我不知道确切的细节(我住的地方是凌晨 1 点),但我可以进行研究,我相信 BalusC 已经在博客文章或 StackOverflow 中介绍了这个主题。如果我找到有关该主题的信息,我会通知您。
  • 感谢您的回复。它作为一个单独的问题发布。 stackoverflow.com/questions/27540573/…
  • 很抱歉打扰您。但即使经过大量的研究努力,我也没有取得丰硕的成果。
【解决方案2】:

每当你使用类似的东西时

#{someBean.someField}

EL 会查找 someBean.getSomeField() 或 someBean.setSomeField(...) 方法,具体取决于您是在读取该字段还是在其中写入(这可以很容易地从上下文中推断出来)。 JSF 从不直接访问字段(即不使用它的 getter 或 setter)。尝试删除给定字段的 getter 和 setter,你会发现它不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 2012-03-26
    • 2013-04-16
    • 1970-01-01
    相关资源
    最近更新 更多