0

关于在父页面中使用 JSF 2.0 复合组件,我有一个概念性思维障碍。我了解如何为复合组件的操作实现 ActionListener (和其他),但是如何连接父页面以供使用?例如,我希望我的登录复合组件执行身份验证,并在完成后通过事件(ActionListener?)通知父页面的支持 bean 进行一些 UI 初始化工作。这里的关键是登录组件会说,“嘿,我完成了,用户很好。轮到你了。”

提前感谢您的帮助。

和平。

克里斯

4

1 回答 1

0

我发现您可以完成此操作的一种方法是使用复合组件 + 自定义组件类型 + ActionSource2 + 系统事件

在您的复合集的接口中设置组件类型(未定义时,实现(Mojarra 或 MyFaces)使用默认组件类型。

<cc:interface componentType="example.Login">
  <cc:attribute name="text" type="java.lang.String"/>
  <cc:attribute name="actionExpression" method-signature="void method()"/>
</cc:interface>

<cc:implementation>
    <p>
      <h:outputLabel value="User"/>
      <h:inputText id="user"/>
    </p>
    <p>
      <h:outputLabel value="Password"/>
      <h:inputSecret id="password"/>
    </p>
</cc:implementation>

该组件类型是实现 NamingContainer 的 java 类(UINamingContainer 是实现该接口的组件的子类)。接下来,您必须实现 ActionSource2,以便在验证用户时生成操作事件。

verifyng 必须在验证用户和密码组件之后进行(不是您的验证,而是 JSF PROCESS VALIDATIONS)。为了知道验证何时发生,我们使用系统事件。

这是自定义组件的代码示例。该类实现 ActionSource2 接口的方法并覆盖广播以处理 ActionEvent。我在 Mojarra 中使用了一些特定的类(因为 ActionSource 和 ActionSource2 之间的遗留问题)。

 @FacesComponent("example.Login") //Component type in the composite
@ListenerFor(systemEventClass=PostValidateEvent.class) //Event to listen for user and password verification
public class LoginComponent extends UINamingContainer implements  ActionSource2{

    @Override
    public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
        if(event instanceof PostValidateEvent){
            System.out.println("post validate");
        }
        super.processEvent(event);
        String user=(String) ((HtmlInputText)findComponent("user")).getValue();
        String password=(String) ((HtmlInputSecret)findComponent("password")).getValue();
        System.out.println("user: "+user);
        System.out.println("password: "+password);
        //a simple logic for verification
        if(user != null && user.equals("victor") && password != null && password.equals(user)){
            System.out.println("user ok");
            queueEvent(new ActionEvent(this));
        }
    }


    private MethodExpression exp;

    @Override
    public MethodExpression getActionExpression() {
        return exp;
    }

    @Override
    public void setActionExpression(MethodExpression action) {
        exp=action;
    }

    @Override
    public MethodBinding getAction() {
        return exp != null ? new MethodBindingMethodExpressionAdapter(exp): null;
    }

    @Override
    public void setAction(MethodBinding action) {
        setActionExpression(new MethodExpressionMethodBindingAdapter(action));
    }

    private MethodBinding actionListener;

    @Override
    public MethodBinding getActionListener() {
        return actionListener;
    }

    @Override
    public void setActionListener(MethodBinding actionListener) {
        this.actionListener=actionListener;
    }

    private boolean i;

    @Override
    public boolean isImmediate() {
        return i;
    }

    @Override
    public void setImmediate(boolean immediate) {
        this.i=immediate;
    }

    List<ActionListener> listeners=new LinkedList<ActionListener>();

    @Override
    public void addActionListener(ActionListener listener) {
        listeners.add(listener);
    }

    @Override
    public ActionListener[] getActionListeners() {
        return listeners.toArray(new ActionListener[0]);
    }

    @Override
    public void removeActionListener(ActionListener listener) {
        listeners.remove(listener);
    }

    @Override
     public void broadcast(FacesEvent event) throws AbortProcessingException {
        super.broadcast(event);

        if (event instanceof ActionEvent) {
            FacesContext context = getFacesContext();
            MethodBinding binding = getActionListener();
            if (binding != null) {
                binding.invoke(context, new Object[] { event });
            }

            ActionListener listener = context.getApplication().getActionListener();
            if (listener != null) {
                listener.processAction((ActionEvent) event);
            }
        }
    }

}

这是使用页面中的代码:

<ez:login actionExpression="#{bean.logged}"/>
于 2011-01-30T00:28:38.267 回答