h:button 和 h:commandButton 之间的区别
Posted
技术标签:
【中文标题】h:button 和 h:commandButton 之间的区别【英文标题】:Difference between h:button and h:commandButton 【发布时间】:2012-10-15 18:02:27 【问题描述】:在 JSF 2 中,h:button
和 h:commandButton
有什么区别?
【问题讨论】:
我发现this link 更有用更详细 【参考方案1】:<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。如果 SEO 在给定 URL 上很重要,您最好使用 <h:outputLink>
或 <h:link>
。如有必要,您可以在生成的 HTML <a>
元素上添加一些 CSS,使其看起来像一个按钮。
请注意,虽然您可以将引用方法的 EL 表达式放在 outcome
属性中,如下所示,
<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>
、How do I process GET query string URL parameters in backing bean on page load? 获得 GET 请求参数
<h:commandButton>
<h:commandButton>
生成一个 HTML <input type="submit">
按钮,该按钮默认使用 HTTP POST 方法提交父 <h:form>
,并调用附加到 action
、actionListener
和/或 <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 pattern),以便目标 URL 变为可收藏。
<h:commandButton>
通常专门用于提交 POST 表单,而不是执行页面到页面导航。通常,action
指向一些业务操作,例如将表单数据保存在 DB 中,这会返回一个String
结果。
<h:commandButton ... action="#bean.save" />
与
public String save()
// ...
return "otherpage";
返回null
或void
将带您回到相同的视图。也返回一个空字符串,但它会重新创建任何视图范围的 bean。如今,使用现代 JSF2 和 <f:ajax>
,操作往往只是返回到相同的视图(因此,null
或 void
),其中结果由 ajax 有条件地呈现。
public void save()
// ...
另见:
How to navigate in JSF? How to make URL reflect current page (and not previous one) When should I use h:outputLink instead of h:commandLink? Differences between action and actionListener【讨论】:
action="otherpage" 如何变成 action="/contextpath/currentpage.xhtml" ?不应该是 action="/contextpath/otherpage.xhtml" 这些实际上是无关的。<h:form>
将始终生成一个指向当前请求的 URL 的 <form action>
。 <h:commandButton action="otherpage">
基本上指示 JSF 在 POST 请求完成时执行对给定视图 ID 的转发。
“即使这最终导致浏览器地址栏中的(可添加书签的)URL 发生变化,但这对 SEO 不友好。搜索机器人不会跟随 onclick 中的 URL”为什么会这样?跨度>
Searchbots 通常只解释 HTML 而忽略 JS(和 CSS)。尽管 Google 正在尝试破译 JS 代码。您应该将搜索机器人视为禁用 JS 的用户。【参考方案2】:
h:button
- 点击h:button
发出一个可收藏的GET
请求。
h:commandbutton
- h:commandbutton
发出 POST 请求,而不是 get 请求,将表单数据发送回服务器。
【讨论】:
【参考方案3】: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" />
【讨论】:
为 h:commandButton 生成的代码似乎不正确。生成的操作应该是 page.xhtml 而不是 index.xhtml。【参考方案4】:这摘自本书 - Ed Burns 和 Chris Schalk 的完整参考书
h:commandButton 与 h:button
h:commandButton|h:commandLink 和 h:button|h:link ?
2.0
中引入了后两个组件以启用书签
JSF 页面,当与视图参数功能一起使用时。
h:button|h:link 和 h:commandButton|h:commandLink.
首先,
h:button|h:link
导致浏览器发出 HTTP GET 请求,而h:commandButton|h:commandLink
执行表单 POST。这 表示页面中具有由 用户,例如文本字段、复选框等,不会自动 使用h:button|h:link
时提交到服务器。导致 要使用h:button|h:link
提交的值,必须执行额外操作 使用“查看参数”功能拍摄。这两种组件的第二个主要区别是
h:button|h:link
有一个结果属性来描述下一步要去哪里 而h:commandButton|h:commandLink
为此使用了一个动作属性 目的。这是因为前者不会导致 ActionEvent 在事件系统中,而后者是。最后,对于完全理解这一点最重要的是 功能,
h:button|h:link
组件导致导航系统 被要求在页面呈现期间得出结果,并且 这个问题的答案被编码在页面的标记中。在 相比之下,h:commandButton|h:commandLink
组件导致 要求导航系统得出 POSTBACK 的结果 从页面。这是时间上的差异。始终渲染 发生在 POSTBACK 之前。
【讨论】:
【参考方案5】:以下是JSF javadocs 对commandButton
action
属性的评价:
MethodExpression 表示要在何时调用的应用程序操作 该组件由用户激活。表达式必须计算 到一个不带参数的公共方法,并返回一个对象 (调用 toString() 以得出逻辑结果) 它被传递给此应用程序的 NavigationHandler。
如果有人能解释这与此页面上的任何答案有什么关系,那将对我很有启发。 action
指的是某个页面的文件名而不是方法,这似乎很明显。
【讨论】:
以上是关于h:button 和 h:commandButton 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章