Перехват исключений с помощью пользовательских обработчиков событий JSF - PullRequest
1 голос
/ 21 января 2009

Есть ли способ создать пользовательский класс ActionListener в JSF, чтобы я мог перехватить исключение, если оно возникает при нажатии кнопки, используя мой собственный класс 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.

Что я неправильно настроил, чтобы страница ошибки не отображалась при возникновении исключения?

Ответы [ 4 ]

3 голосов
/ 21 января 2009

Javadoc для Application.setActionListener :

Установите для ActionListener по умолчанию значение зарегистрировано для всех ActionSource компоненты.

ActionListener , установленный в Приложении, не отвечает за вызов других слушателей. Он не вызывает ничего, установленного с помощью атрибута actionListener или тега f: actionListener . Это является ответственным за обработку атрибута action , который связан с методами, которые возвращают строку с навигационным регистром (см. Get / setAction для ActionSource *) 1024 *).

Итак, слушатель в приложении не может отлавливать события от других слушателей, потому что он их не вызывает.

Резюме:

<h:commandButton action="#{bean.foo1}" actionListener="#{bean.foo2}">
    <f:actionListener type="type.Foo3" />
</h:commandButton>
  1. foo1: (метод public String foo1 () ) использует face-config ActionListener
  2. foo2: (метод public void foo2 (ActionEvent) ) использует MethodExpressionActionListener
  3. Foo3: (класс открытый класс Foo3 реализует ActionListener ), зарегистрирован непосредственно на компоненте

Кроме того, вероятно, лучше использовать этот шаблон для создания ActionListener, зарегистрированного вface-config.xml:

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 голос
/ 20 августа 2010

У вас есть лишний слеш (/) в строке:

<to-view-id>/error.jsp/<to-view-id>

Должно быть

<to-view-id>/error.jsp<to-view-id>
0 голосов
/ 07 сентября 2010

Я считаю, что вам нужно:

<from-view-id>/*</from-view-id>

после правила навигации и до случая навигации.

0 голосов
/ 21 января 2009

Здесь вы можете найти, как реализовать Action Listener

и здесь, как зарегистрировать прослушиватель для компонентов (даже пример для команды Button).

...