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:buttonh: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 上很重要,您最好使用 &lt;h:outputLink&gt;&lt;h:link&gt;。如有必要,您可以在生成的 HTML &lt;a&gt; 元素上添加一些 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 请求的结果调用方法,请改用&lt;h:commandButton&gt;,见下文。或者,如果您打算作为 GET 请求的结果调用方法,请前往 Invoke JSF managed bean action on page load 或者如果您还通过 &lt;f:param&gt;、How do I process GET query string URL parameters in backing bean on page load? 获得 GET 请求参数


&lt;h:commandButton&gt;

&lt;h:commandButton&gt; 生成一个 HTML &lt;input type="submit"&gt; 按钮,该按钮默认使用 HTTP POST 方法提交父 &lt;h:form&gt;,并调用附加到 actionactionListener 和/或 &lt;f:ajax listener&gt;(如果有)的操作。 &lt;h:form&gt; 是必需的。

例如

<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 变为可收藏。

&lt;h:commandButton&gt; 通常专门用于提交 POST 表单,而不是执行页面到页面导航。通常,action 指向一些业务操作,例如将表单数据保存在 DB 中,这会返回一个String 结果。

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

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

返回nullvoid 将带您回到相同的视图。也返回一个空字符串,但它会重新创建任何视图范围的 bean。如今,使用现代 JSF2 和 &lt;f:ajax&gt;,操作往往只是返回到相同的视图(因此,nullvoid),其中结果由 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" 这些实际上是无关的。 &lt;h:form&gt;始终生成一个指向当前请求的 URL 的 &lt;form action&gt;&lt;h:commandButton action="otherpage"&gt; 基本上指示 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:commandLinkh:button|h:link ?

2.0 中引入了后两个组件以启用书签 JSF 页面,当与视图参数功能一起使用时。

h:button|h:linkh: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 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

在表单中按 Enter 时执行的默认操作

ivew ui

标准库按键中断

esp8266 第二章 如何通过Makefile 重写esp工程结构

iview table内渲染proptip组件

iview 在Table组件render 中使用Poptip组件 阿星小栈