当前位置: 首页 > 面试题库 >

为什么请求facelet时多次调用BackingBean方法?

孙佐
2023-03-14
问题内容

这些天,我正在学习JSF + Facelets。我有一个BackingBean和Facelet
xHTML页面。当我请求facelet页时(仅一次),backing-bean-method被多次调用

这可能是什么原因?

我看不到什么特别的东西。提前致谢。

这是方面:

<?xml version="1.0" encoding="UTF-8" ?>
<!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:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Insert title here</title>
</head>
<body>
<ui:composition template="index.xhtml">
    <ui:define name="content">
        <h:form>Name: <h:inputText id="nameFilterPattern" value="#{kundenBackingBean.nameFilterPattern}" /><h:commandButton value="Suchen"/></h:form>
        <h:dataTable var="kunde" value="#{kundenBackingBean.kunden}" rowClasses="rowHighlight, rowOrdinary">
            <h:column> 
                <f:facet name="header">
                    <h:outputText value="Kundennr" />
                </f:facet>
                <h:outputText value="#{kunde.kundenNr}"/>
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputText value="Name" />
                </f:facet>
                <h:outputText value="#{kunde.name}"/>
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputText value="Vorname" />
                </f:facet>
                <h:outputText value="#{kunde.vorname}"/>
            </h:column>
            <h:column>
                <h:outputLink>Details</h:outputLink>
            </h:column>
        </h:dataTable>
    </ui:define>
</ui:composition>
</body>
</html>

这是支持豆。方法getKunden被多次调用:

@ManagedBean
@SessionScoped
public class KundenBackingBean extends AbstractBackingBean {

    private String nameFilterPattern;

    public List<Kunde> getKunden(){
        System.out.println("getKunden");
        return getApplication().getKunden(getNameFilterPattern());
    }

    public String getNameFilterPattern() {
        return nameFilterPattern;
    }

    public void setNameFilterPattern(String nameFilterPattern) {
        System.out.println("Name filter: " + nameFilterPattern);
        this.nameFilterPattern = nameFilterPattern;
    }

}

问题答案:

Bean的getter在那里就 可以 从视图侧 访问
模型数据。可以多次调用它们。通常一或两次,但可以长到几百倍,特别是当还使用UIData组件或其他属性比value(如rendereddisabled等)。通常这没有害处,因为它只是一个简单的方法调用,通常不要在吸气剂中进行昂贵的数据加载逻辑或计算。预加载/初始化通常是在bean构造函数和/或bean操作方法中完成的。实际上,getter应该仅
返回 数据(如有必要,还应进行 延迟加载 )。

如果getApplication().getKunden(getNameFilterPattern());执行的任务非常昂贵,则应将其移至bean构造函数,bean
@PostConstruct方法,bean初始化块或bean操作方法,或在getter中引入 延迟加载 模式。这是一个示例,显示了如何执行所有操作:

public class Bean {
    private String nameFilterPattern;
    private List<Kunde> kunden;

    // Load during bean construction.
    public Bean() {
        this.kunden = getApplication().getKunden(getNameFilterPattern());
    }

    // OR load during @PostConstruct (will be invoked AFTER construction and resource injection.
    @PostConstruct
    public void init() {
        this.kunden = getApplication().getKunden(getNameFilterPattern());
    }

    // OR during bean initialization (this is invoked BEFORE construction and will apply to ALL constructors).
    {
        this.kunden = getApplication().getKunden(getNameFilterPattern());
    }

    // OR during bean action method (invoked from h:commandLink/Button).
    public String submit() {
        this.kunden = getApplication().getKunden(getNameFilterPattern());
        return "navigationCaseOutcome";
    }

    // OR using lazy loading pattern in getter method.
    public List<Kunde> getKunden() {
        if (this.kunden == null) 
            this.kunden = getApplication().getKunden(getNameFilterPattern());
        }
        return this.kunden;
    }

在您的特定情况下,我认为这是@PostConstruct(如果nameFilterPattern要从GET请求参数获取),或者只是bean操作方法(如果nameFilterPattern要从POST表单输入字段获取)是合适的。

要了解有关JSF生命周期的更多信息,您可能会发现这篇自我实践文章很有用。



 类似资料:
  • 我遇到了一个奇怪的问题。对于单个HTTP请求,我的servlet的doGet方法被多次调用。每隔10-12秒重新运行一次,直到初始过程完成。 下面是我的servlet代码 下面是web.xml中的映射 我使用的是SEAM和JSF,但这是一个独立的servlet。日志中也没有例外。我还验证了INIT方法只被调用一次。重复的是服务方法。所有重新运行的标识哈希代码都是相同的(System.Identit

  • 问题内容: 我正在使用Swift开发iOS通用应用程序,使用自动布局功能,并且仅支持纵向模式。 我发现打过多次。而是在启动MyApp时仅被调用一次。 为什么要多次调用?是否会按顺序对每个(,等)进行约束? 任何信息将不胜感激。 问题答案: 仅被调用一次:需要加载视图时。 ,但是,每个运行循环都会在已存在或已对其调用的任何视图上调用一次- 这包括每当将子视图添加到视图,滚动,调整大小等时。

  • 问题内容: 关于的简单代码。是SessionScoped Bean,是RequestScoped Bean 内 我的问题是被叫很多。会告诉我们该方法在什么阶段被调用。首次加载页面时,请在阶段6-进行约 5次 呼叫。该页面上有一个,因此我在其中键入一些内容,然后单击(命令按钮)。然后在阶段1-> 4期间再呼叫 12次 。每个阶段调用此方法 3-4次 。然后,此属性的get 方法的setter方法(即

  • 问题内容: ,它在它的第一个版本,也有类似的代码如下: 通过使用惰性过滤器集合,它可以过滤满足给定谓词的前5个元素(在这种情况下,可以被3整除),而不必求值数组中的 每个 元素。 但是,答案随后表明,每个元素可以多次调用’谓词(对于范围为1 … 15的元素,其谓词为3次,结果为0,则为两次)。 懒惰评估此过滤器效率低下的原因是什么?有什么方法可以避免多次评估同一元素? 问题答案: 问题所在 这里的

  • 我读在初始渲染时只被调用一次,但我看到它被渲染了多次。 似乎我创建了一个递归循环。 组件didMount调度动作来获取数据 一旦接收到数据,它就会触发成功操作,将数据存储在redux状态。 父反应组件连接到redux存储,并且具有mapStateToProps用于刚刚在上述步骤中更改的条目 父渲染子组件(通过变量编程选择) 子组件的组件didMount再次被调用 它消除了获取数据的操作 我想这就是