如何第一次访问bean?

时间:2014-10-02 19:37:26

标签: jsf el facelets managed-bean

我正在浏览oracle中的tutorial Java EE 7。

这是一个在输入框中获取用户名的简单表单:

<h:body>
        <h:form>
            <h:graphicImage url="#{resource['images:duke.waving.gif']}"
                            alt="Duke waving his hand"/>
            <h2>Hello, my name is Duke. What's yours?</h2>
            <h:inputText id="username"
                         title="My name is: "
                         value="#{hello.name}"
                         required="true"
                         requiredMessage="Error: A name is required."
                         maxlength="25" />
            <p></p>
            <h:commandButton id="submit" value="Submit" action="response">
            </h:commandButton>
            <h:commandButton id="reset" value="Reset" type="reset">
            </h:commandButton>
        </h:form>

我看到代码中使用了value="#{hello.name}"。这条线做了什么?

这是tutorial link中提到的内容:

网页通过表达式语言(EL)值表达式#{hello.name}连接到Hello托管bean,该表达式从托管bean中检索name属性的值。

Q1)但是第一次加载表单时,hello bean没有附加name属性。所以提取那个应该返回null是否正确?

Q2)其次,输入框中输入的值如何绑定到hello bean的name属性?

事实上,在提交表单后,页面将被重定向到&#34; response.xhtml&#34;其中hello bean的name属性的值以相同的方式获取,即#{hello.name}

1 个答案:

答案 0 :(得分:1)

简答:

  • Q1:正确
  • Q2:
    1. 在每个页面呈现元素上,绑定到#{hello.name}将收到Hello.getName()方法返回的值。
    2. 在每个表单提交上(如果表单有效),将使用 Hello.setName(param) 等于param元素调用value,绑定到{{ 1}}

更长的回答:

你有:

  1. #{hello.name},注明了@Named@RequestScoped
  2. 的班级 在Hello.java <h:inputText value="#{hello.name}" />内的
  3. <h:form>index.xhtml
  4. #{hello.name}内的
  5. <h2>

    <小时/> 先决条件:

    • response.xhtmlCDI annotation

    • 部署应用程序时,服务器&#34;注册&#34; @Named作为托管bean。

    • Hello.java可以用作@Named,但如果没有提供参数,那么该bean将被注册为&#34;更低级的类名&#34;,所以在部署应用程序后,我们可以在任何需要的地方使用 hello

    • @Named(name="explicitHelloName")表示每个@RequestScoped个实例的数据将会#34;生存&#34;仅在请求 - 响应期间(有关范围详细信息,请参阅this answer。)

    • This article大大描述了JSF生命周期。我们对它的两个目标很感兴趣: HelloRENDER_RESPONSE


    让我们一步一步走:

    予。浏览器请求UPDATE_MODEL_VALUES

    FacesServlet的职责(因为我们将所有index.xhtml个文件映射到*.xhtml内的Faces Servlet)是为了构建html并将其作为回复返回。

    构建包含多个阶段(详情请见here),其中一个阶段,RENDER-RESPONSE:

    1. 构建web.xml
    2. 递归建立UIViewRoot的孩子。
    3. 在儿童的 2)期间,有一些EL表达式,这些表达式被解析了#34;。

      在您的情况下,我们有UIViewRoot表达式,绑定到#{hello.name}的{​​{1}}(valueUIInput)。

      h:inputText将呈现为HTML UIInput

      FacesServlet&#34;了解&#34;此输入的值应取自<h:inputText>表示的值。 获得价值:

      1. FacesServlet&#34; ask&#34;来自容器(服务器)的 hello
      2. 容器搜索已注册的 hello ,找到<input type="text">,将其实例化并提供给FacesServlet。
      3. FacesServlet呼吁 #{hello.name} JavaBean convention获取Hello.java个实例的&#34;名称&#34;)并获取{{{ 1}}的私有字段 getName() ,课后实例化为Hello
      4. FacesServlet在没有Hello的情况下将name写入响应,在index.xhtml上,您会看到空输入。

      5. II。按提交按钮

        ...且表单有效,有null阶段(更详细here),.

        对于我们的<input>组件,FacesServlet再次搜索 hello ,找到value的实例并在其上调用 UPDATE_MODEL 。 由于h:inputText的{​​{1}}属性为Hello,浏览器即将收到 response.xhtml 的内容(这不是重定向,请参阅this answer,因此,setName(value) hello 未被重新创建)。


        III。 response.xhtml

        ...有<h:commandButtons>,所以,FacesServlet必须再次解析它,如前所述。

        但是在当前请求中,action已经过实例化,其response字段已设置(@RequestScoped阶段),并且您输入的值为<h3>Hello, #{hello.name}</h3> },所以,Hello被写入响应并显示在浏览器中。

        <小时/> 有关表达式的更多详细信息,请参见here

        修改

        如果您在name上使用UPDATE_MODEL_VALUES,那么在 II 之后会有一个重定向到response.xhtml,并且input bean会重新创建,所以,你会看到&#34;你好,&#34; (<h3>Hello, YOUR_SUBMITTED_TO_INPUT_TEXT_VALUE</h3>将为<h:comandButton action="response?faces-redirect=true"/>