h:button和h:commandButton的区别

78
在JSF 2中,h:buttonh:commandButton有什么区别?

1
我发现这个链接更有用和详细。 - exexzian
5个回答

114

<h:button>

<h:button>生成一个HTML <input type="button">元素。 生成的元素使用JavaScript导航到由属性outcome给定的页面,使用HTTP GET请求。

例如:

<h:button value="GET button" outcome="otherpage" />

会生成什么

<input type="button" onclick="window.location.href='/contextpath/otherpage.xhtml'; return false;" value="GET button" />
尽管这样做会导致浏览器地址栏中的URL改变(可以加入书签),但这并不利于SEO。搜索机器人不会跟随onclick中的URL。如果给定的URL很重要,最好使用<h:outputLink><h:link>。您可以在生成的HTML<a>元素上添加一些CSS,使其看起来像一个按钮。
请注意,虽然您可以将引用outcome属性中方法的EL表达式放在下面,
<h:button value="GET button" outcome="#{bean.getOutcome()}" />

当你点击按钮时,它不会被调用。相反,它已经在渲染包含该按钮的页面时被调用,目的是获取嵌入在生成的onclick代码中的导航结果。如果您曾尝试使用动作方法语法,如 outcome="#{bean.action}",您将通过面对javax.el.ELException: Could not find property actionMethod in class com.example.Bean来提示此错误/误解。

如果您打算作为POST请求的结果调用方法,请改用<h:commandButton>,请参见下文。或者,如果您打算作为GET请求的结果调用方法,请前往Invoke JSF managed bean action on page load,或者如果您还有通过<f:param>传递GET请求参数,请前往How do I process GET query string URL parameters in backing bean on page load?


<h:commandButton>

<h:commandButton> 生成一个HTML <input type="submit"> 按钮,使用HTTP POST方法默认提交父级<h:form>并调用与actionactionListener和/或<f:ajax listener>相关联的操作(如果有的话)。 必须使用<h:form>

例如:

<h:form id="form">
    <h:commandButton id="button" value="POST button" action="otherpage" />
</h:form>

会生成什么

<form id="form" name="form" method="post" action="/contextpath/currentpage.xhtml" enctype="application/x-www-form-urlencoded">
    <input type="hidden" name="form" value="form" />
    <input type="submit" name="form:button" value="POST button" />
    <input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="...." autocomplete="off" />
</form>

请注意,此方法将提交到当前页面(表单操作URL将显示在浏览器地址栏中)。之后将转发到目标页面,浏览器地址栏中的URL不会发生任何更改。您可以向结果值添加?faces-redirect=true参数以触发POST后的重定向(根据Post-Redirect-Get模式),使目标URL可作为书签使用。

<h:commandButton>通常专门用于提交POST表单,而不是执行页面导航。通常,action指向某些业务操作,例如将表单数据保存到数据库中,并返回一个String结果。

<h:commandButton ... action="#{bean.save}" />

带有

public String save() {
    // ...
    return "otherpage";
}

返回 nullvoid 将使您回到相同的视图。返回空字符串也是如此,但它会重新创建任何视图作用域的bean。现在,随着现代JSF2和 <f:ajax>,更多的操作只是返回到相同的视图(因此,nullvoid),结果由ajax有条件地呈现。

public void save() {
    // ...
}

另请参见:


1
action="otherpage" 怎么变成 action="/contextpath/currentpage.xhtml"?它不应该是 action="/contextpath/otherpage.xhtml" 吗? - Geek
3
这两件事实际上是没有关联的。<h:form> 标签会始终生成一个指向当前请求 URL 的 <form action> 标签。<h:commandButton action="otherpage"> 标签基本上是指示 JSF 在 POST 请求完成后执行到给定视图 ID 的跳转。 - BalusC
尽管这会导致浏览器地址栏中的URL更改(可作为书签保存),但这并不利于SEO。搜索机器人不会跟随onclick中的URL。为什么呢? - Geek
2
搜索机器人通常只解释HTML并忽略JS(和CSS)。尽管谷歌正在尝试解密JS代码。您应该将搜索机器人视为禁用JS的用户。 - BalusC

7

h:button - 点击 h:button 会发起可被书签化的 GET 请求。

h:commandbutton - 而 h:commandbutton 则会发起一个 POST 请求,将表单数据发送回服务器。


4

h:commandButton必须包含在一个h:form中,并具有两种导航方式:通过设置action属性进行静态导航和通过设置actionListener属性进行动态导航。因此,它更加先进,如下所示:

<h:form>
    <h:commandButton action="page.xhtml" value="cmdButton"/>
</h:form>

这段代码将生成以下HTML:

<form id="j_idt7" name="j_idt7" method="post" action="/jsf/faces/index.xhtml" enctype="application/x-www-form-urlencoded">

与之相反,h:button更加简单,只用于静态或基于规则的导航,如下所示

<h:button outcome="page.xhtml" value="button"/>

生成的HTML代码为:
 <title>Facelet Title</title></head><body><input type="button" onclick="window.location.href='/jsf/faces/page.xhtml'; return false;" value="button" />

1
h:commandButton的生成代码似乎不正确。生成的操作应该是page.xhtml而不是index.xhtml。 - Arun Gupta

4

这段内容摘自《The Complete Reference by Ed Burns & Chris Schalk》一书。

h:commandButton vs h:button

h:commandButton|h:commandLinkh:button|h:link有什么区别?

后两个组件在2.0中引入,用于与“View Parameters”功能配合使用,实现可书签的JSF页面。

h:button|h:linkh:commandButton|h:commandLink之间有三个主要区别。

首先,h:button|h:link导致浏览器发出HTTP GET请求,而h:commandButton|h:commandLink执行表单提交。这意味着,当使用h:button|h:link时,页面中任何由用户输入值的组件(如文本字段、复选框等)都不会自动提交到服务器。要使值随h:button|h:link提交,需要使用“View Parameters”功能采取额外操作。

第二个主要区别是,h:button|h:link具有outcome属性,用于描述下一步要去哪里,而h:commandButton|h:commandLink使用action属性来实现此目的。这是因为前者不会在事件系统中导致ActionEvent,而后者会。

最后,也是最重要的一点,h:button|h:link组件在渲染页面时会请求导航系统推导结果,并将答案编码到页面标记中。相比之下,h:commandButton|h:commandLink组件会在POSTBACK后请求导航系统推导结果。这是时间上的差异。渲染总是在POSTBACK之前发生。


0

以下是JSF javadocs关于commandButton action属性的说明:

MethodExpression表示应用程序在用户激活此组件时要调用的操作。表达式必须评估为一个不带参数的公共方法,并返回一个对象(其toString()被调用以派生逻辑结果),该对象将传递给此应用程序的NavigationHandler。

如果有人能解释这与本页上任何答案有什么关系,那对我来说会很有启发性。看起来很清楚,action是指某个页面的文件名,而不是一个方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接