我希望在我的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");
}
并在Portal构造函数中
public Portal() {
list.add( new Bla() );
}
但这不是我想要的方式......
答案 0 :(得分:11)
这是因为无法从包含匿名类的包外部访问匿名类。
这是演示幕后发生的事情:
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;
}
}
答案 1 :(得分:0)
问题已经很久了,但我今天遇到了同样的问题,但仅仅因为我已经从Jetty 7切换到Tomcat 7.
我通过用GlassFish EL库替换Jasper EL库来解决这个问题。