有没有办法在JSF中创建自定义ActionListener
类,以便在使用我自己的ActionListener类按下命令按钮时发生异常时拦截异常
我尝试使用以下代码:
firstpage.jsp
<f:view>
<html>
<head>
<title>firstpage</title>
</head>
<body>
<h:form>
<h:commandButton id="button" value="submit"
actionListener="#{databasebean.fetchUserName}"/>
</h:form>
</body>
</html>
</f:view>
Dao.java
package getexception;
import java.sql.*;
import java.util.ArrayList;
import javax.faces.event.ActionEvent;
public class Dao {
String firstname;
private Connection con=null;
private Statement stmt = null;
private ResultSet rst = null;
private ArrayList ar;
String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
String url = "jdbc:odbc:" + "new";
public Dao() {
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getFirstname() {
return firstname;
}
public void fetchUserName(ActionEvent ae) throws Exception{
Driver d= (Driver)Class.forName(driver).newInstance();
con = DriverManager.getConnection(url,"","");
stmt = con.createStatement();
rst=stmt.executeQuery("select firstname from employee where firstname like '%e'");
if(rst.next()) {
this.setFirstname(rst.getString("firstname"));
}
rst.close();
stmt.close();
con.close();
}}
NewActionListener.java
package getexception;
import com.sun.faces.application.ActionListenerImpl;
import javax.faces.application.Application;
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
public class NewActionListener extends ActionListenerImpl{
public void processAction(ActionEvent event) {
try {
System.out.println("try block");
super.processAction(event);
} catch (Exception exception) {
System.out.println("catch block");
FacesContext facesContext = FacesContext.getCurrentInstance();
Application application = facesContext.getApplication();
NavigationHandler navigationHandler = application.getNavigationHandler();
navigationHandler.handleNavigation(facesContext,null,"exceptionNavigation");
facesContext.renderResponse();
}
}}
faces-config.xml
<faces-config xmlns="http://java.sun.com/JSF/Configuration">
<managed-bean>
<managed-bean-name>databasebean</managed-bean-name>
<managed-bean-class>getexception.Dao</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<navigation-rule>
<navigation-case>
<from-outcome>exceptionNavigation</from-outcome>
<to-view-id>/error.jsp/<to-view-id>
</navigation-case>
</navigation-rule>
<application>
<action-listener>getexception.NewActionListener</action-listener>
</application>
<managed-bean>
<managed-bean-name>backing_hellopage</managed-bean-name>
<managed-bean-class>getexception.backing.Hellopage</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
error.jsp
<html>
<f:view>
<head>
<title>firstpage</title>
</head>
<body>
<h:form>
<h:outputText value="Exception succesfully navigated"/>
</h:form>
</body>
</f:view>
</html>
代码生成了一个SQL异常,但它没有向我显示error.jsp
页面。
我错误配置了什么,以便在触发异常时没有显示错误页面?
答案 0 :(得分:3)
Application.setActionListener的javadoc:
将默认的ActionListener设置为 已注册所有 ActionSource 组件。
应用程序上设置的ActionListener不负责调用其他侦听器。它不会通过actionListener属性或f:actionListener标记调用任何设置。 负责处理action属性,该属性绑定到返回导航案例字符串的方法(请参阅ActionSource上的get / setAction )。
因此,应用程序上的侦听器无法捕获来自其他侦听器的事件,因为它不会调用它们。
要点:
<h:commandButton action="#{bean.foo1}" actionListener="#{bean.foo2}">
<f:actionListener type="type.Foo3" />
</h:commandButton>
顺便说一句,使用此模式创建在faces-config.xml中注册的ActionListener可能更好:
public class MyActionListener implements ActionListener {
private final ActionListener delegate;
public MyActionListener(ActionListener delegate) {
this.delegate = delegate;
}
public void processAction(ActionEvent event)
throws AbortProcessingException {
delegate.processAction(event);
}
}
当JSF框架自行配置时,它会将底层的ActionListener实现传递给构造函数。这适用于许多JSF文物(工厂等)。
答案 1 :(得分:1)
行中有一个不必要的斜杠(/):
<to-view-id>/error.jsp/<to-view-id>
应该是
<to-view-id>/error.jsp<to-view-id>
答案 2 :(得分:0)
在这里您可以找到如何implement an Action Listener
在这里,如何register a listener on components(甚至是commandButton的一个例子)。
答案 3 :(得分:0)
我相信你需要:
<from-view-id>/*</from-view-id>
导航规则之后和导航案例之前。