Jsf action和actionListener之间的区别
Jsf action和actionListener之间的区别,jsf,jsf-2,action,actionlistener,Jsf,Jsf 2,Action,Actionlistener,action和actionListener之间有什么区别,我应该在什么时候使用action和actionListener?在调用action并确定下一页的位置之前,actionListener首先被触发,并有一个修改响应的选项。 如果在同一页面上有多个按钮,这些按钮应位于同一位置,但执行的操作略有不同,则可以对每个按钮使用相同的操作,但使用不同的ActionListener来处理略有不同的功能 以下是描述关系的链接: actionListener 如果您想在执行真正的业务操作之前有一个钩子,请使
action
和actionListener
之间有什么区别,我应该在什么时候使用action
和actionListener
?在调用action并确定下一页的位置之前,actionListener首先被触发,并有一个修改响应的选项。
如果在同一页面上有多个按钮,这些按钮应位于同一位置,但执行的操作略有不同,则可以对每个按钮使用相同的操作,但使用不同的ActionListener来处理略有不同的功能
以下是描述关系的链接:
actionListener
如果您想在执行真正的业务操作之前有一个钩子,请使用actionListener
,例如记录它,和/或设置附加属性(by),和/或访问调用该操作的组件(通过参数可用)。因此,纯粹是为了在调用真正的业务操作之前做好准备
默认情况下,actionListener
方法具有以下签名:
import javax.faces.event.ActionEvent;
// ...
public void actionListener(ActionEvent event) {
// ...
}
import javax.faces.event.AjaxBehaviorEvent;
// ...
public void ajaxListener(AjaxBehaviorEvent event) {
// ...
}
它应该声明如下,没有任何方法括号:
<h:commandXxx ... actionListener="#{bean.actionListener}" />
请注意无参数方法表达式中括号的重要性。如果它们不存在,JSF仍然希望方法具有ActionEvent
参数
<h:commandXxx ...>
<f:ajax execute="@form" listener="#{bean.ajaxListener()}" render="@form" />
</h:commandXxx>
如果您使用的是EL2.2+,那么您可以通过
声明多个操作侦听器方法
请注意binding
属性中括号的重要性。如果它们不存在,EL会令人困惑地抛出一个javax.EL.PropertyNotFoundException:在com.example.Bean
类型上找不到属性“actionListener1”,因为binding
属性默认解释为值表达式,而不是方法表达式。添加EL 2.2+样式的括号可以透明地将值表达式转换为方法表达式。另见a.o
行动 如果要执行业务操作,并在必要时处理导航,请使用
action
。操作
方法可以(因此,不必)返回一个字符串
,该字符串将用作导航案例结果(目标视图)。返回值null
或void
将使其返回到同一页面并保持当前视图范围的活动状态。空字符串或相同视图ID的返回值也将返回到同一页面,但重新创建视图范围,从而销毁任何当前活动的视图范围bean,如果适用,重新创建它们
操作
方法可以是任何有效的方法,也可以是使用EL 2.2参数的方法,例如:
使用此方法:
public void edit(Item item) {
// ...
}
请注意,当您的操作方法仅返回字符串时,您也可以在action
属性中精确指定该字符串。因此,这完全是笨拙的:
使用此无意义的方法返回硬编码字符串:
public String goToNextpage() {
return "nextpage";
}
相反,只需将硬编码字符串直接放入属性:
请注意,这反过来表明了一个糟糕的设计:通过POST导航。这对用户和搜索引擎优化都不友好。所有这些都在中进行了解释,并应作为
另见
f:ajax监听器 自从JSF2.x以来,还有第三种方法,即
在Mojarra中,AjaxBehaviorEvent
参数是可选的,下面的参数同样适用
public void ajaxListener() {
// ...
}
但在MyFaces中,它会抛出一个MethodNotFoundException
。当您想省略参数时,以下两种JSF实现都适用
<h:commandXxx ...>
<f:ajax execute="@form" listener="#{bean.ajaxListener()}" render="@form" />
</h:commandXxx>
有关execute
和render
属性的说明,请参阅
调用顺序
actionListener
s总是在action
之前调用,调用顺序与在视图中声明并附加到组件的顺序相同。f:ajax侦听器始终在任何操作侦听器之前调用。下面的例子:
将按以下顺序调用这些方法:
Bean#ajaxListener()
Bean\actionListener()
ActionListenerType#processAction()
Bean\actionListenerBinding()
Bean#setProperty()
Bean\action()
异常处理
actionListener
支持特殊异常:。如果此异常是从actionListener
方法引发的,那么JSF将跳过任何剩余的操作侦听器和操作方法,并继续直接呈现响应。您不会看到错误/异常页面,但是JSF会记录它。每当从actionListener
引发任何其他异常时,也会隐式执行此操作。因此,如果您打算通过业务异常导致的错误页面来阻止该页面,那么您肯定应该在操作
方法中执行该作业
如果使用actionListener
的唯一原因是让void
方法返回到同一页面,那么这是一个糟糕的方法。action
方法也可以完美地返回void
,这与一些IDE通过EL验证让您相信的相反。请注意,示例中到处都是这种actionListener
s。这的确是错误的。不要以此为借口自己也这么做
然而,在ajax请求中,需要一个特殊的异常处理程序。这与是否使用
的listener
属性无关。如BalusC所示,默认情况下,actionListener
会接受异常,但在JSF2.0中,这一点还有一些。也就是说,它不只是吞咽和记录,而是发布异常
这是通过ca实现的
<h:commandXxx ...>
<f:ajax listener="#{bean.ajaxListener}" />
</h:commandXxx>
import javax.faces.event.AjaxBehaviorEvent;
// ...
public void ajaxListener(AjaxBehaviorEvent event) {
// ...
}
public void ajaxListener() {
// ...
}
<h:commandXxx ...>
<f:ajax execute="@form" listener="#{bean.ajaxListener()}" render="@form" />
</h:commandXxx>
<h:commandXxx ... action="#{bean.action}">
<f:ajax execute="@form" render="@form" />
</h:commandXxx>
context.getApplication().publishEvent(context, ExceptionQueuedEvent.class,
new ExceptionQueuedEventContext(context, exception, source, phaseId)
);
<exception-handlerfactory>
com.foo.myExceptionHandler
</exception-handlerfactory>
@ManagedBean
@RequestScoped
public class MyBean {
public void actionMethod(ActionEvent event) {
FacesContext.getCurrentInstance().getApplication().subscribeToEvent(ExceptionQueuedEvent.class, new SystemEventListener() {
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
ExceptionQueuedEventContext content = (ExceptionQueuedEventContext)event.getSource();
throw new RuntimeException(content.getException());
}
@Override
public boolean isListenerForSource(Object source) {
return true;
}
});
throw new RuntimeException("test");
}
}
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<h:form>
<h:commandButton value="test" actionListener="#{myBean.actionMethod}"/>
</h:form>
</h:body>
</html>