代码之家  ›  专栏  ›  技术社区  ›  justastefan

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

  •  6
  • justastefan  · 技术社区  · 15 年前

    我想在我的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>
    

    那么我的会话范围门户如下所示:

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

    当我运行此代码时,它将显示良好。但是,当您尝试通过单击“clickme”命令链接来执行操作时,会发生以下异常:

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

    是否有任何方法可以显示匿名类的列表,从中可以看到一个方法(在本例中 ITemplate.action() )可以执行吗?

    编辑:

    当我使用一个(内部)类时,它是有效的。例如:

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

    在门户构造函数中

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

    但这不是我想要的方式…

    2 回复  |  直到 10 年前
        1
  •  10
  •   BalusC    15 年前

    这是因为匿名类不能从包含匿名类的包外部访问。

    下面是一个在幕后发生的演示:

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

    尝试在与相同的包中执行此操作 Portal 类,然后在包外的另一个类中再次调用。在另一个包中,最后一行将抛出完全相同的异常。这就是El正在努力解决的问题,因为它是基于思考的。

    我不认为有其他方法可以很好地解决这个问题,而不仅仅是创建一个 public (内部) class . 反射(因此也包括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;
        }
    
    }
    
        2
  •  0
  •   Lii bob    10 年前

    这个问题很古老,但我今天也遇到了同样的问题,只是因为我从7号码头转到了7号Tomcat。

    我通过用Glassfish EL库替换Jasper EL库来解决这个问题。