首页 文章

父页面支持Bean中的JSF 2.0复合组件事件

提问于
浏览
0

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

在此先感谢您的帮助 .

和平 .

克里斯

1 回答

  • 0

    我发现你可以通过 composite component + custom component type + ActionSource2 + system events 找到一种方法 .

    在组合集的接口中,组件类型(未定义时,实现(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,以便在验证用户时生成操作事件 .

    验证必须在验证用户和密码组件之后(不是您的验证,而是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}"/>
    

相关问题