1

ジャワ:

public class MyBean {
  ...
  public Handler getHandler(){  
    return new Handler(){  
      public void handle(ActionEvent e){...}  
    }
  }
  ...
}

public interface Handler{
  void handle(ActionEvent e);
}

xhtml:

<h:commandButton ... actionListener="#{myBean.handler.handle}"/>

私はTomcat 6.0環境にいます。これは Java では一般的なパターンですが、EL メソッド バインディングでは機能しないようです。例外があります:

javax.faces.event.MethodExpressionActionListener processAction SEVERE): Received 'java.lang.IllegalAccessException' when invoking action listener '#{myBean.handler.handle}' for component 'j_id115'
javax.faces.event.MethodExpressionActionListener processAction SEVERE): java.lang.IllegalAccessException: Class org.apache.el.parser.AstValue can not access a member of class MyBean$1 with modifiers "public"
...
4

3 に答える 3

1

はい、できますが、いくつか間違ったことをしました。

まず、#handle()-method は public として宣言する必要があります。これは、インターフェイスの public メソッドの実装であるためです。

public class MyBean {
  ...
  public Handler getHandler(){  
    return new Handler(){  
      public void handle(){...}  
    };
  }

}

2 番目のポイントは、actionListener として Handler を呼び出していることですが、必要なのは #handle() メソッドを呼び出すことです。

<h:commandButton actionListener="#{myBean.handler.handle}"/>

また、インターフェイス (および実装) のメソッド シグネチャから ActionEvent を省略する必要があります。

public interface Handler {
  public void handle();
}
于 2012-11-15T10:53:07.283 に答える
1

これが思ったより微妙だった…

Java から、内部クラスで public メソッドを呼び出すことに問題はありません。

MyBean myBean = getMyBean();
Handler handler = myBean.getHandler();
handler.handle(event); // OK

リフレクションを使用すると、それがどのように行われるかによって異なります。このメソッドは、宣言されているとおりに呼び出すことができます (1):

Method getHandlerMethod = MyBean.class.getMethod("getHandler");
Method handleMethod = getHandlerMethod.getReturnType().getMethod("handle", ActionEvent.class);
handleMethod.invoke(handler, event); // OK, invoking declared method works

または、内部クラスで定義されているように呼び出すこともできます (2):

Method handleMethod = handler.getClass().getMethod("handle", ActionEvent.class);
handleMethod.invoke(handler, event) // throws IllegalAccessException

明らかに、3 番目のオプションがあり、それが機能します (3):

Method handleMethod = handler.getClass().getDeclaredMethod("handle", ActionEvent.class);
handleMethod.invoke(handler, event) // OK

残念ながら、私の JSF 環境 (Tomcat 6.0 と JSF mojarra 1.2 および icefaces 1.8.2) は (3) ではなく (2) のアプローチを実装しているため、私の例は機能しません。

于 2012-11-15T17:58:53.770 に答える
0

handle() メソッドを ActionListener として指定すると機能するはずです。

<h:commandButton ... actionListener="#{myBean.handler.handle}"/>

ActionListener インターフェイスの実装クラスを指定するには、「f:actionListener」タグを使用できます。

<h:commandButton>
    <f:actionListener type="com.bla.SomeActionListenerImplementation" />
</h:commandButton>

しかし、あなたの MyBean クラスは ActionListener インターフェイスを実装していないため、これはあなたのケースでは機能しません...

于 2012-11-15T10:50:00.753 に答える