【问题标题】:Difference between h:button and h:commandButtonh:button 和 h:commandButton 之间的区别
【发布时间】:2012-10-15 18:02:27
【问题描述】:

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

【问题讨论】:

标签: jsf button jsf-2


【解决方案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() {
    // ...
}

另见:

【讨论】:

  • 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 javadocscommandButton action 属性的评价:

      MethodExpression 表示要在何时调用的应用程序操作 该组件由用户激活。表达式必须计算 到一个不带参数的公共方法,并返回一个对象 (调用 toString() 以得出逻辑结果) 它被传递给此应用程序的 NavigationHandler。

      如果有人能解释这与此页面上的任何答案有什么关系,那将对我很有启发。 action 指的是某个页面的文件名而不是方法,这似乎很明显。

      【讨论】:

        猜你喜欢
        • 2014-03-01
        • 2016-10-31
        • 1970-01-01
        • 1970-01-01
        • 2021-12-25
        • 2020-05-10
        • 2014-09-20
        • 2010-10-28
        相关资源
        最近更新 更多