action和actionListener之间的差异

action和actionListener之间的差异

是什么区别actionactionListener,什么时候应该使用actionactionListener



慕村225694
浏览 1231回答 4
4回答

慕桂英4014372

的ActionListener使用actionListener,如果你想有一个钩子之前得到执行的实际业务操作,如记录它,和/或设置附加属性(通过<f:setPropertyActionListener>),和/或访问其调用的动作(这是可以由组件ActionEvent参数)。因此,在实际业务操作被调用之前,纯粹是为了准备目的。该actionListener方法默认具有以下签名:import&nbsp;javax.faces.event.ActionEvent;//&nbsp;...public&nbsp;void&nbsp;actionListener(ActionEvent&nbsp;event)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...}它应该声明如下,没有任何方法括号:<h:commandXxx&nbsp;...&nbsp;actionListener="#{bean.actionListener}"&nbsp;/>请注意,您不能通过EL 2.2&nbsp;传递其他参数。但是,您可以ActionEvent通过传递和指定自定义参数来完全覆盖参数。以下示例有效:<h:commandXxx&nbsp;...&nbsp;actionListener="#{bean.methodWithoutArguments()}"&nbsp;/><h:commandXxx&nbsp;...&nbsp;actionListener="#{bean.methodWithOneArgument(arg1)}"&nbsp;/> <h:commandXxx&nbsp;...&nbsp;actionListener="#{bean.methodWithTwoArguments(arg1,&nbsp;arg2)}"&nbsp;/>public&nbsp;void&nbsp;methodWithoutArguments()&nbsp;{}public&nbsp;void&nbsp;methodWithOneArgument(Object&nbsp;arg1)&nbsp;{}public&nbsp;void&nbsp;methodWithTwoArguments(Object&nbsp;arg1,&nbsp;Object&nbsp;arg2)&nbsp;{}请注意无参数方法表达式中括号的重要性。如果它们不存在,JSF仍然期望一个带ActionEvent参数的方法。如果您使用的是EL 2.2+,则可以通过声明多个动作侦听器方法<f:actionListener binding>。<h:commandXxx&nbsp;...&nbsp;actionListener="#{bean.actionListener1}"> &nbsp;&nbsp;&nbsp;&nbsp;<f:actionListener&nbsp;binding="#{bean.actionListener2()}"&nbsp;/> &nbsp;&nbsp;&nbsp;&nbsp;<f:actionListener&nbsp;binding="#{bean.actionListener3()}"&nbsp;/></h:commandXxx>public&nbsp;void&nbsp;actionListener1(ActionEvent&nbsp;event)&nbsp;{}public&nbsp;void&nbsp;actionListener2()&nbsp;{}public&nbsp;void&nbsp;actionListener3()&nbsp;{}请注意binding属性中括号的重要性。如果它们不存在,EL会混淆地抛出一个javax.el.PropertyNotFoundException: Property 'actionListener1' not found on type com.example.Bean,因为该binding属性默认被解释为值表达式,而不是方法表达式。添加EL 2.2+样式括号透明地将值表达式转换为方法表达式。另请参阅ao&nbsp;为什么我能够将<f:actionListener>绑定到任意方法(如果JSF不支持它)?行动使用action,如果你想执行业务操作,并在必要时处理导航。该action方法可以(因此,不必)返回String将用作导航案例结果(目标视图)的方法。返回值为null或void将使其返回到同一页面并使当前视图范围保持活动状态。空字符串或相同视图ID的返回值也将返回到同一页面,但会重新创建视图范围,从而销毁任何当前活动的视图范围bean,并在适用时重新创建它们。该action方法可以是任何有效的MethodExpression,也可以是使用EL 2.2参数的方法,如下所示:<h:commandXxx&nbsp;value="submit"&nbsp;action="#{bean.edit(item)}"&nbsp;/>用这种方法:public&nbsp;void&nbsp;edit(Item&nbsp;item)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...}请注意,当您的action方法仅返回一个字符串时,您也可以只在该action属性中指定该字符串。因此,这完全是笨拙的:<h:commandLink&nbsp;value="Go&nbsp;to&nbsp;next&nbsp;page"&nbsp;action="#{bean.goToNextpage}"&nbsp;/>使用这种无意义的方法返回硬编码字符串:public&nbsp;String&nbsp;goToNextpage()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"nextpage";}相反,只需将该硬编码字符串直接放在属性中:<h:commandLink&nbsp;value="Go&nbsp;to&nbsp;next&nbsp;page"&nbsp;action="nextpage"&nbsp;/>请注意,这反过来表明设计不好:通过POST导航。这不是用户也不是SEO友好。这一切都在我何时应该使用h:outputLink而不是h:commandLink?应该被解决为<h:link&nbsp;value="Go&nbsp;to&nbsp;next&nbsp;page"&nbsp;outcome="nextpage"&nbsp;/>另请参见如何在JSF中导航?如何使URL反映当前页面(而不是之前的页面)。f:ajax监听器从JSF 2.x开始,第三种方式就是<f:ajax listener>。<h:commandXxx&nbsp;...> &nbsp;&nbsp;&nbsp;&nbsp;<f:ajax&nbsp;listener="#{bean.ajaxListener}"&nbsp;/></h:commandXxx>该ajaxListener方法默认具有以下签名:import&nbsp;javax.faces.event.AjaxBehaviorEvent;//&nbsp;...public&nbsp;void&nbsp;ajaxListener(AjaxBehaviorEvent&nbsp;event)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...}在Mojarra中,AjaxBehaviorEvent参数是可选的,下面的效果很好。public&nbsp;void&nbsp;ajaxListener()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...}但是在MyFaces中,它会抛出一个MethodNotFoundException。当你想省略参数时,下面的两个JSF实现都适用。<h:commandXxx&nbsp;...> &nbsp;&nbsp;&nbsp;&nbsp;<f:ajax&nbsp;execute="@form"&nbsp;listener="#{bean.ajaxListener()}"&nbsp;render="@form"&nbsp;/></h:commandXxx>Ajax侦听器在命令组件上并不真正有用。它们对输入和选择组件<h:inputXxx>/&nbsp;更有用<h:selectXxx>。在命令组件中,只需坚持action和/或actionListener清晰,以及更好的自我记录代码。而且,例如actionListener,f:ajax listener不支持返回导航结果。<h:commandXxx&nbsp;...&nbsp;action="#{bean.action}"> &nbsp;&nbsp;&nbsp;&nbsp;<f:ajax&nbsp;execute="@form"&nbsp;render="@form"&nbsp;/></h:commandXxx>有关execute和render属性的说明,请前往了解PrimeFaces进程/更新和JSF f:ajax执行/渲染属性。调用顺序所述actionListeners的总是调用之前的action以相同的顺序,因为它们是在视图被声明和连接到该组件。将f:ajax listener始终调用之前的任何动作侦听器。那么,以下示例:<h:commandButton&nbsp;value="submit"&nbsp;actionListener="#{bean.actionListener}"&nbsp;action="#{bean.action}"> &nbsp;&nbsp;&nbsp;&nbsp;<f:actionListener&nbsp;type="com.example.ActionListenerType"&nbsp;/> &nbsp;&nbsp;&nbsp;&nbsp;<f:actionListener&nbsp;binding="#{bean.actionListenerBinding()}"&nbsp;/> &nbsp;&nbsp;&nbsp;&nbsp;<f:setPropertyActionListener&nbsp;target="#{bean.property}"&nbsp;value="some"&nbsp;/> &nbsp;&nbsp;&nbsp;&nbsp;<f:ajax&nbsp;listener="#{bean.ajaxListener}"&nbsp;/></h:commandButton>将按以下顺序调用方法:Bean#ajaxListener()Bean#actionListener()ActionListenerType#processAction()Bean#actionListenerBinding()Bean#setProperty()Bean#action()异常处理在actionListener支持一个特殊的例外:AbortProcessingException。如果从actionListener方法抛出此异常,则JSF将跳过任何剩余的动作侦听器和操作方法,并继续直接呈现响应。您不会看到错误/异常页面,但JSF会记录它。每当从一个异常抛出任何其他异常时,也会隐式地执行此操作actionListener。因此,如果您打算通过错误页面阻止页面作为业务异常的结果,那么您肯定应该在该action方法中执行该作业。如果使用a的唯一理由actionListener是让void方法返回到同一页面,那么这是一个糟糕的方法。这些action方法可以完美地返回void,相反,某些IDE让您通过EL验证可以相信。请注意,PrimeFaces展示的例子actionListener在所有地方都充满了这种情况。这确实是错的。不要以此为借口自己也这样做。但是,在ajax请求中,需要一个特殊的异常处理程序。这与您是否使用listener属性<f:ajax>无关。有关解释和示例,请转到JSF ajax请求中的异常处理。

蛊毒传说

TL; DR:将ActionListener在他们登记前的顺序S(也可以是多个)执行action答案很长:企业action通常调用EJB服务,并且如果必要的话也设置最终结果和/或导航到不同的视图,如果这不是您正在做的事情actionListener更合适,即当用户与组件交互时,例如h:commandButton或者h:link他们可以通过在actionListenerUI组件的属性中传递托管bean方法的名称或实现ActionListener接口并将实现类名称传递actionListener给UI组件的属性来处理。
打开App,查看更多内容
随时随地看视频慕课网APP