action和actionListener之间的区别 [英] Differences between action and actionListener

查看:147
本文介绍了action和actionListener之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

actionactionListener有什么区别,我什么时候应该使用actionactionListener?

What is the difference between action and actionListener, and when should I use action versus actionListener?

推荐答案

actionListener

如果要在执行真正的业务操作之前之前,请使用actionListener.进行记录和/或设置其他属性(通过

actionListener

Use actionListener if you want have a hook before the real business action get executed, e.g. to log it, and/or to set an additional property (by <f:setPropertyActionListener>), and/or to have access to the component which invoked the action (which is available by ActionEvent argument). So, purely for preparing purposes before the real business action gets invoked.

actionListener方法默认具有以下签名:

The actionListener method has by default the following signature:

import javax.faces.event.ActionEvent;
// ...

public void actionListener(ActionEvent event) {
    // ...
}

它应该声明如下,没有任何方法括号:

And it's supposed to be declared as follows, without any method parentheses:

<h:commandXxx ... actionListener="#{bean.actionListener}" />

请注意,EL 2.2无法传递 additional 参数.但是,可以通过传递并指定自定义参数来完全覆盖ActionEvent参数.以下示例是有效的:

Note that you can't pass additional arguments by EL 2.2. You can however override the ActionEvent argument altogether by passing and specifying custom argument(s). The following examples are valid:

<h:commandXxx ... actionListener="#{bean.methodWithoutArguments()}" />
<h:commandXxx ... actionListener="#{bean.methodWithOneArgument(arg1)}" />
<h:commandXxx ... actionListener="#{bean.methodWithTwoArguments(arg1, arg2)}" />

public void methodWithoutArguments() {}
public void methodWithOneArgument(Object arg1) {}
public void methodWithTwoArguments(Object arg1, Object arg2) {}

请注意无参数方法表达式中括号的重要性.如果不存在,JSF仍然希望使用带有ActionEvent参数的方法.

Note the importance of the parentheses in the argumentless method expression. If they were absent, JSF would still expect a method with ActionEvent argument.

如果您使用的是EL 2.2+,则可以通过<f:actionListener binding>声明多个动作侦听器方法.

If you're on EL 2.2+, then you can declare multiple action listener methods via <f:actionListener binding>.

<h:commandXxx ... actionListener="#{bean.actionListener1}">
    <f:actionListener binding="#{bean.actionListener2()}" />
    <f:actionListener binding="#{bean.actionListener3()}" />
</h:commandXxx>

public void actionListener1(ActionEvent event) {}
public void actionListener2() {}
public void actionListener3() {}

请注意binding属性中括号的重要性.如果不存在,EL会令人困惑地抛出javax.el.PropertyNotFoundException: Property 'actionListener1' not found on type com.example.Bean,因为binding属性默认情况下被解释为值表达式,而不是方法表达式.添加EL 2.2+样式括号会透明地将值表达式转换为方法表达式.另请参阅为什么是我可以绑定< f:actionListener>到JSF不支持的任意方法?

Note the importance of the parentheses in the binding attribute. If they were absent, EL would confusingly throw a javax.el.PropertyNotFoundException: Property 'actionListener1' not found on type com.example.Bean, because the binding attribute is by default interpreted as a value expression, not as a method expression. Adding EL 2.2+ style parentheses transparently turns a value expression into a method expression. See also a.o. Why am I able to bind <f:actionListener> to an arbitrary method if it's not supported by JSF?

如果要执行业务操作并在必要时处理导航,请使用action. action方法可以(因此不是必须)返回String,它将用作导航案例的结果(目标视图).返回值nullvoid将使其返回同一页面并使当前视图范围保持活动状态.空字符串或相同视图ID的返回值也将返回同一页面,但是将重新创建视图范围,从而销毁任何当前活动的视图范围的bean,并在适用时重新创建它们.

Use action if you want to execute a business action and if necessary handle navigation. The action method can (thus, not must) return a String which will be used as navigation case outcome (the target view). A return value of null or void will let it return to the same page and keep the current view scope alive. A return value of an empty string or the same view ID will also return to the same page, but recreate the view scope and thus destroy any currently active view scoped beans and, if applicable, recreate them.

action方法可以是任何有效的 MethodExpression ,也是使用EL 2.2参数的参数,例如:

The action method can be any valid MethodExpression, also the ones which uses EL 2.2 arguments such as below:

<h:commandXxx value="submit" action="#{bean.edit(item)}" />

使用此方法:

public void edit(Item item) {
    // ...
}

请注意,当您的操作方法仅返回一个字符串时,您也可以仅在action属性中指定该字符串.因此,这太笨拙了:

Note that when your action method solely returns a string, then you can also just specify exactly that string in the action attribute. Thus, this is totally clumsy:

<h:commandLink value="Go to next page" action="#{bean.goToNextpage}" />

通过这种无意义的方法,可以返回硬编码的字符串:

With this senseless method returning a hardcoded string:

public String goToNextpage() {
    return "nextpage";
}

相反,只需将该硬编码字符串直接放在属性中:

Instead, just put that hardcoded string directly in the attribute:

<h:commandLink value="Go to next page" action="nextpage" />

请注意,这反过来又表明设计不好:通过POST导航.这既不是用户也不是SEO友好. 何时应使用h:outputLink而不是h:commandLink?,并且应该解决为

Please note that this in turn indicates a bad design: navigating by POST. This is not user nor SEO friendly. This all is explained in When should I use h:outputLink instead of h:commandLink? and is supposed to be solved as

<h:link value="Go to next page" outcome="nextpage" />

另请参见自JSF 2.x以来,还有第三种方法,即<f:ajax listener>.

Since JSF 2.x there's a third way, the <f:ajax listener>.

<h:commandXxx ...>
    <f:ajax listener="#{bean.ajaxListener}" />
</h:commandXxx>

ajaxListener方法默认具有以下签名:

The ajaxListener method has by default the following signature:

import javax.faces.event.AjaxBehaviorEvent;
// ...

public void ajaxListener(AjaxBehaviorEvent event) {
    // ...
}

在Mojarra中,AjaxBehaviorEvent参数是可选的,下面的效果很好.

In Mojarra, the AjaxBehaviorEvent argument is optional, below works as good.

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

但是在MyFaces中,它将抛出MethodNotFoundException.当您想省略参数时,下面的方法在这两种JSF实现中均有效.

But in MyFaces, it would throw a MethodNotFoundException. Below works in both JSF implementations when you want to omit the argument.

<h:commandXxx ...>
    <f:ajax execute="@form" listener="#{bean.ajaxListener()}" render="@form" />
</h:commandXxx>

Ajax侦听器在命令组件上并不是真正有用的.它们在输入和选择组件<h:inputXxx>/<h:selectXxx>时更有用.在命令组件中,请坚持使用action和/或actionListener以获得清晰性和更好的自记录代码.而且,与actionListener一样,f:ajax listener不支持返回导航结果.

Ajax listeners are not really useful on command components. They are more useful on input and select components <h:inputXxx>/<h:selectXxx>. In command components, just stick to action and/or actionListener for clarity and better self-documenting code. Moreover, like actionListener, the f:ajax listener does not support returning a navigation outcome.

<h:commandXxx ... action="#{bean.action}">
    <f:ajax execute="@form" render="@form" />
</h:commandXxx>

有关executerender属性的说明,请转到

For explanation on execute and render attributes, head to Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes.

actionListener始终在之前 被调用,其顺序与在视图中声明并附加到组件的顺序相同. f:ajax listener始终在任何动作侦听器之前 调用.因此,下面的示例:

The actionListeners are always invoked before the action in the same order as they are been declared in the view and attached to the component. The f:ajax listener is always invoked before any action listener. So, the following example:

<h:commandButton value="submit" actionListener="#{bean.actionListener}" action="#{bean.action}">
    <f:actionListener type="com.example.ActionListenerType" />
    <f:actionListener binding="#{bean.actionListenerBinding()}" />
    <f:setPropertyActionListener target="#{bean.property}" value="some" />
    <f:ajax listener="#{bean.ajaxListener}" />
</h:commandButton>

将按以下顺序调用方法:

Will invoke the methods in the following order:

  1. Bean#ajaxListener()
  2. Bean#actionListener()
  3. ActionListenerType#processAction()
  4. Bean#actionListenerBinding()
  5. Bean#setProperty()
  6. Bean#action()
  1. Bean#ajaxListener()
  2. Bean#actionListener()
  3. ActionListenerType#processAction()
  4. Bean#actionListenerBinding()
  5. Bean#setProperty()
  6. Bean#action()


异常处理

actionListener支持一个特殊的例外: AbortProcessingException .如果从actionListener方法引发此异常,则JSF将跳过所有剩余的动作侦听器和该动作方法,并继续直接呈现响应.您将不会看到错误/异常页面,但是JSF会将其记录下来.每当从actionListener引发任何其他异常时,也将隐式完成此操作.因此,如果由于业务异常而打算通过错误页面来阻止该页面,那么您肯定应该在action方法中执行该作业.


Exception handling

The actionListener supports a special exception: AbortProcessingException. If this exception is thrown from an actionListener method, then JSF will skip any remaining action listeners and the action method and proceed to render response directly. You won't see an error/exception page, JSF will however log it. This will also implicitly be done whenever any other exception is being thrown from an actionListener. So, if you intend to block the page by an error page as result of a business exception, then you should definitely be performing the job in the action method.

如果使用actionListener的唯一原因是让void方法返回同一页面,那么那是一个不好的选择.与某些IDE通过EL验证让您相信的相反,action方法也可以完美地返回void.请注意, PrimeFaces展示示例在所有地方都充满了这种actionListener.这确实是错误的.请勿以此为借口自己做.

If the sole reason to use an actionListener is to have a void method returning to the same page, then that's a bad one. The action methods can perfectly also return void, on the contrary to what some IDEs let you believe via EL validation. Note that the PrimeFaces showcase examples are littered with this kind of actionListeners over all place. This is indeed wrong. Don't use this as an excuse to also do that yourself.

但是,在ajax请求中,需要一个特殊的异常处理程序.这与是否使用<f:ajax>listener属性无关.有关说明和示例,请访问 JSF ajax请求中的异常处理.

In ajax requests, however, a special exception handler is needed. This is regardless of whether you use listener attribute of <f:ajax> or not. For explanation and an example, head to Exception handling in JSF ajax requests.

这篇关于action和actionListener之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆