已弃用的Richfaces javax.faces.el.MethodBinding替代方案使用

5

我发现这段代码可以编程创建一个富faces下拉菜单。但是其中一些代码已经过时了。有没有人告诉我用什么替换过时的调用呢?

谢谢

     public HtmlDropDownMenu getMyMenu()
 {
  HtmlDropDownMenu menu = new HtmlDropDownMenu();
  menu.setValue( "Node Select" );

  HtmlMenuItem menuItem = new HtmlMenuItem();
  // TODO programmatically pass from getNodes into a String[] rather than an ArrayList of SelectItems
  String subOption = "myBox";   
  menuItem.setValue( subOption );

  Application app = FacesContext.getCurrentInstance().getApplication();
  javax.faces.el.MethodBinding mb = app.createMethodBinding( "#{PrismBacking.onItemClick}", new Class[] { ActionEvent.class } );
  menuItem.setActionListener( mb );

  menu.getChildren().add( menuItem );
  return( menu );
 }

 public void onItemClick( ActionEvent event )
 {
  Object obj = event.getSource();

  if( obj instanceof HtmlMenuItem )
  {
   HtmlMenuItem item = (HtmlMenuItem)obj;
   if( item != null )
   {
    lastItem = item.getValue().toString();

   }
  }
 }

过时的代码行是:

   javax.faces.el.MethodBinding mb = app.createMethodBinding( "#{PrismBacking.onItemClick}", new Class[] { ActionEvent.class } );
  menuItem.setActionListener( mb );

1
顺便说一句,这不是RichFaces特有的。那些只是标准的JSF API方法(来自“javax.faces”包),因此我添加了JSF标记。 - BalusC
3个回答

12

通常情况下,所有的弃用都在API文档中进行了说明,包括替代方式的详细信息。

为了清晰地了解,在这里介绍JSF1.2之前和之后创建动作和动作侦听器的方法:

在JSF1.0/1.1中创建动作绑定:

MethodBinding action = FacesContext.getCurrentInstance().getApplication()
    .createMethodBinding("#{bean.action}", new Class[0]);
uiCommandComponent.setAction(action);

在JSF 1.0/1.1中创建ActionListener绑定:

MethodBinding actionListener =  FacesContext.getCurrentInstance().getApplication()
    .createMethodBinding("#{bean.actionListener}", new Class[] {ActionEvent.class});
uiCommandComponent.setActionListener(actionListener);

在JSF 1.2或更高版本中创建Action表达式:

FacesContext context = FacesContext.getCurrentInstance();
MethodExpression action = context.getApplication().getExpressionFactory()
    .createMethodExpression(context.getELContext(), "#{bean.action}", String.class, new Class[0]);
uiCommandComponent.setActionExpression(action);

在JSF 1.2或更新版本中创建ActionListener表达式:

FacesContext context = FacesContext.getCurrentInstance();
MethodExpression actionListener = context.getApplication().getExpressionFactory()
    .createMethodExpression(context.getELContext(), "#{bean.actionListener}", null, new Class[] {ActionEvent.class});
uiCommandComponent.addActionListener(new MethodExpressionActionListener(actionListener));
为了避免大量的样板代码,可以将其封装在帮助方法中(如果必要,在帮助程序/实用程序类中),例如:

为了避免大量的样板代码,可以将其封装在帮助方法中(如果必要,在帮助程序/实用程序类中),例如:

public static MethodExpression createAction(String actionExpression, Class<?> returnType) {
    FacesContext context = FacesContext.getCurrentInstance();
    return context.getApplication().getExpressionFactory()
        .createMethodExpression(context.getELContext(), actionExpression, returnType, new Class[0]);
}

public static MethodExpressionActionListener createActionListener(String actionListenerExpression) {
    FacesContext context = FacesContext.getCurrentInstance();
    return new MethodExpressionActionListener(context.getApplication().getExpressionFactory()
        .createMethodExpression(context.getELContext(), actionListenerExpression, null, new Class[] {ActionEvent.class}));
}

这样你只需要像下面这样使用它:

uiCommandComponent.setActionExpression(createAction("#{bean.action}", String.class);
uiCommandComponent.addActionListener(createActionListener("#{bean.actionListener}");

1
如往常一样全面。 - Bozho
虽然这很老了,但我认为这里有一个错别字应该被修正。在您的第二个框(JSF 1.1)中,uiComp.addActionListenerActionListener作为参数,而uiComp.setActionListenerMethodBinding参数作为参数,因此您的第二个框无法编译。(至少在MyFaces impl 1.1中) - mohdajami

7

官方文档已经明确说明:

Application.createMethodBinding

已弃用。应该调用getExpressionFactory()然后使用 ExpressionFactory.createMethodExpression(javax.el.ELContext, java.lang.String, java.lang.Class, java.lang.Class[])来替代。

以下是使用方法:

MethodExpression methodExpression = 
    application.getExpressionFactory().createMethodExpression(
         FacesContext.getCurrentInstance().getELContext(), 
         "#{PrismBacking.onItemClick}", 
         null, 
         new Class[] { ActionEvent.class });
menuItem.setActionExpression(methodExpression);

Bozho感谢您的指引。由于我是Java新手,不知道如何按照手册的说明操作。您能否为我编写一个示例片段来替换上面代码中已弃用的部分(我最初是剪切和粘贴的)?谢谢。 - volvox
2
ActionListener 方法的返回类型应该为 void,因此您应该传递 null 而不是 Object.class - BalusC
谢谢你们两个。它可以正常渲染,但是在点击getMyMenu方法中指定的subOption时,我得到了一个空白页面,控制台中也没有任何内容,即使在onItemClick方法中放置日志记录。我已经阅读了Javadocs,但我太新了,无法将它们解释为如何更改后备bean上的任何内容,以便我可以从jsp页面中使用它。你能指点我一个好的教程吗?谢谢。 - volvox

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接