2010-06-08 10 views
6

Chcę mieć ogólne menu w mojej aplikacji JSF (MyFaces 1.2).Jak wywołać akcję JSF na anonimowej klasie? EL nie może uzyskać do niego dostępu

<h:form> 
    <h:dataTable id="dt1" value="#{portal.actionList}" var="item"> 
    <f:facet name="header"> 
     <h:outputText value="Menu" /> 
    </f:facet> 
    <h:column> 
     <h:commandLink action="#{item.action}"> 
      <h:outputText value="clickme"/> 
     </h:commandLink> 
    </h:column> 
    </h:dataTable> 
</h:form> 

Wtedy mój portal na sesji-Scope będzie wyglądać następująco:

class Portal { 
    private ArrayList<IAction> list = new ArrayList<IAction>(); 

    public Portal() { 
     list.add(new IAction() { 
       public action() { 
        log.info("called action here"); 
       } 
     }); 
    } 
    public ArrayList<IAction> getActionList() { 
     return list; 
    } 
} 

Kiedy uruchomić tego kodu spowoduje wyświetlenie w porządku. Ale podczas próby wykonania tej operacji poprzez kliknięcie „clickme” link polecenia - następujący wyjątek wystąpią:

Class org.apache.el.parser.AstValue can not access a member of class Portal$1 with modifiers "public" 

Czy istnieje jakiś sposób, aby wyświetlić listę anonimowych klas, z których metoda (w tym przykładzie ITemplate.action()) może zostać wykonany?

Edit:

To działa, gdy używam (wewnętrznej) klasę. Jak na przykład:

class Bla implements IAction { 
     public void action() { 
      log.info("yes, i am working"); 
     } 

i konstruktora Portal

public Portal() { 
    list.add(new Bla()); 
} 

ale nie jest to sposób, w jaki chcę go ...

Odpowiedz

10

To dlatego anonimowych klasy nie są dostępne z zewnątrz opakowania zawierające anonimową klasę.

Oto demonstracja, co dzieje się za kulisami:

public static void main(String[] args) throws Exception { 
    Portal portal = new Portal(); 
    Object list = portal.getClass().getDeclaredMethod("getActionList", null).invoke(portal, null); 
    Object action = list.getClass().getDeclaredMethod("get", new Class[] { int.class }).invoke(list, 0); 
    action.getClass().getDeclaredMethod("action", null).invoke(action, null); 
} 

Spróbuj wykonywania tego w tym samym opakowaniu jako Portal klasie, a potem jeszcze raz w innej klasie poza pakietem. W drugim pakiecie, ostatni wiersz wyrzuciłby dokładnie ten sam wyjątek. Właśnie z tym problemem zmaga się firma EL, ponieważ opiera się na refleksji.

Nie widzę innych sposobów, aby rozwiązać to ładnie niż tylko tworzenie public (wewnętrzna) class. Odbicie (a więc i EL) może uzyskać do nich dostęp z innych pakietów.

public class Portal { 

    private List<IAction> list = new ArrayList<IAction>(); 

    public Portal() { 
     list.add(new IActionImpl()); 
    } 

    public class IActionImpl implements IAction { 
     public void action() { 
      System.out.println("called action here"); 
     } 
    } 

    public List<IAction> getActionList() { 
     return list; 
    } 

} 
+0

to zrozumiałe wyjaśnienie iw tym celu to rozwiązanie działa dobrze. dzięki ++ – justastefan

+0

Nie ma za co. – BalusC

0

Pytanie jest dość stary, ale ja spotkałem Dziś ten sam problem, ale tylko dlatego, że mam przełącznik od Jetty 7 Tomcat 7.

rozwiązać ten problem przez zastąpienie biblioteki Jasper EL z GlassFish Biblioteka EL.

+0

Rozwiązuję również problem z JUEL el –

Powiązane problemy