我正在浏览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}
。
答案 0 :(得分:1)
#{hello.name}
将收到Hello.getName()
方法返回的值。Hello.setName(param)
等于param
元素调用value
,绑定到{{ 1}} 你有:
#{hello.name}
,注明了@Named
和@RequestScoped
Hello.java
<h:inputText value="#{hello.name}" />
内的<h:form>
在index.xhtml
#{hello.name}
内的<h2>
醇>
<小时/> 先决条件:
response.xhtml
是CDI annotation。
部署应用程序时,服务器&#34;注册&#34; @Named
作为托管bean。
Hello.java
可以用作@Named
,但如果没有提供参数,那么该bean将被注册为&#34;更低级的类名&#34;,所以在部署应用程序后,我们可以在任何需要的地方使用 hello 。
@Named(name="explicitHelloName")
表示每个@RequestScoped
个实例的数据将会#34;生存&#34;仅在请求 - 响应期间(有关范围详细信息,请参阅this answer。)
This article大大描述了JSF生命周期。我们对它的两个目标很感兴趣:
Hello
和RENDER_RESPONSE
。
让我们一步一步走:
UPDATE_MODEL_VALUES
FacesServlet的职责(因为我们将所有index.xhtml
个文件映射到*.xhtml
内的Faces Servlet
)是为了构建html并将其作为回复返回。
构建包含多个阶段(详情请见here),其中一个阶段,RENDER-RESPONSE:
web.xml
UIViewRoot
的孩子。在儿童的 2)期间,有一些EL表达式,这些表达式被解析了#34;。
在您的情况下,我们有UIViewRoot
表达式,绑定到#{hello.name}
的{{1}}(value
是UIInput
)。
h:inputText
将呈现为HTML UIInput
。
FacesServlet&#34;了解&#34;此输入的值应取自<h:inputText>
表示的值。
获得价值:
<input type="text">
,将其实例化并提供给FacesServlet。#{hello.name}
(JavaBean convention获取Hello.java
个实例的&#34;名称&#34;)并获取{{{ 1}}的私有字段 getName()
,课后实例化为Hello
。Hello
的情况下将name
写入响应,在index.xhtml上,您会看到空输入。 ...且表单有效,有null
阶段(更详细here),.
对于我们的<input>
组件,FacesServlet再次搜索 hello ,找到value
的实例并在其上调用 UPDATE_MODEL
。
由于h:inputText
的{{1}}属性为Hello
,浏览器即将收到 response.xhtml 的内容(这不是重定向,请参阅this answer,因此,setName(value)
hello 未被重新创建)。
...有<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"/>
)