简体   繁体   English

如何在匿名类上调用JSF操作? EL无法访问它

[英]How to invoke JSF action on an anonymous class? EL cannot access it

I want to have a generic menu in my JSF (MyFaces 1.2) application. 我希望在我的JSF(MyFaces 1.2)应用程序中有一个通用菜单。

<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>

Then my portal on session-scope would look like this: 然后我的会话范围门户网站将如下所示:

 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;
    }
 }

When I run this code it will display fine. 当我运行此代码时,它将显示正常。 But when you try to execute the action by clicking the "clickme" command link - the following exception will occur: 但是当您尝试通过单击“clickme”命令链接执行操作时,将发生以下异常:

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

Is there any way to display a list of anonymous classes, from which an method (in this example ITemplate.action() ) can be executed? 有没有办法显示一个匿名类列表,从中可以执行一个方法(在本例中为ITemplate.action() )?

Edit: 编辑:

It works when I use an (inner) class. 当我使用(内部)类时,它可以工作。 Like for example: 例如:

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

and in the Portal constructor 并在Portal构造函数中

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

But this is not the way I want it... 但这不是我想要的方式......

That's because anonymous classes are not accessible from outside the package containing the anonymous class. 这是因为无法从包含匿名类的包外部访问匿名类。

Here's a demonstration what's happening behind the scenes: 这是演示幕后发生的事情:

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);
}

Try executing this in the same package as Portal class and then once again in another class outside the package. 尝试在与Portal类相同的包中执行此操作,然后再在包外的另一个类中执行此操作。 In the other package, the last line would then throw exactly the same exception. 在另一个包中,最后一行将抛出完全相同的异常。 That's the problem EL is struggling with since it's based on reflection. 这是EL正在努力解决的问题,因为它基于反思。

I don't see other ways to solve this nicely than just creating a public (inner) class . 我没有看到其他方法来解决这个问题,而不仅仅是创建一个public (内部) class Reflection (and thus also EL) can access them from other packages. 反射(以及EL)也可以从其他包中访问它们。

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;
    }

}

The question is quite old but I have met today the same issue but only because I have switch from Jetty 7 to Tomcat 7. 问题已经很老了,但我今天遇到了同样的问题,但仅仅因为我已经从Jetty 7切换到Tomcat 7。

I solve the issue by replacing the Jasper EL library with the GlassFish EL library. 我通过用GlassFish EL库替换Jasper EL库来解决这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM