【问题标题】:Invoking listener for a subset of lifecycle methods in JSF在 JSF 中为生命周期方法的子集调用侦听器
【发布时间】:2017-03-05 15:19:21
【问题描述】:

在实现PhaseListener接口的jsf bean中,beforePhaseafterPhase方法只会在getPhaseId方法指示的阶段前后被调用。这种机制只能让我们选择一个阶段,这两个方法将在之前和之后被调用。
有没有办法告诉 JSF 在生命周期方法的子集(不仅仅是一个)上调用这两种方法(beforePhaseafterPhase)(

  1. 恢复视图
  2. 应用请求值
  3. 过程验证
  4. 更新模型值
  5. 调用应用程序
  6. 渲染响应阶段

)

public class HelloBean implements PhaseListener {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void afterPhase(PhaseEvent phaseEvent) {
        System.out.println("after phase "+phaseEvent.getPhaseId());
    }

    @Override
    public void beforePhase(PhaseEvent phaseEvent) {
        System.out.println("beforePhase "+phaseEvent.getPhaseId());
    }

    public void testMethod(){
        System.out.println("Test Method");
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }
}

【问题讨论】:

    标签: jsf jsf-2 jsf-2.2 phaselistener


    【解决方案1】:

    很遗憾,这是不可能的。作为一项通用工作,您可以像这样实现自定义扩展 PhaseListener:

    public interface MultiplePhasesListener extends PhaseListener {
    
        @Override
        default void beforePhase(PhaseEvent phaseEvent) {
            if (processPhase(phaseEvent.getPhaseId())) {
                beforePhases(phaseEvent);
            }
        }
    
        @Override
        default void afterPhase(PhaseEvent phaseEvent) {
            if (processPhase(phaseEvent.getPhaseId())) {
                afterPhases(phaseEvent);
            }
        }
    
        @Override
        default PhaseId getPhaseId() {
            return PhaseId.ANY_PHASE;
        }
    
        default boolean processPhase(PhaseId phaseId) {
            if (phaseId == null) {
                return false;
            }
            List<PhaseId> phaseIds = getPhaseIds();
            if (phaseIds == null || phaseIds.isEmpty()) {
                return false;
            }
            return phaseIds.contains(phaseId);
        }
    
        void beforePhases(PhaseEvent phaseEvent);
    
        void afterPhases(PhaseEvent phaseEvent);
    
        List<PhaseId> getPhaseIds();
    }
    

    并像这样使用它:

    public class MultiplePhasesListenerImpl implements MultiplePhasesListener {
    
        private static final long serialVersionUID = 1877176187821557447L;
    
        @Override
        public void beforePhases(PhaseEvent phaseEvent) {
            System.out.println(phaseEvent.getPhaseId());
        }
    
        @Override
        public void afterPhases(PhaseEvent phaseEvent) {
            System.out.println(phaseEvent.getPhaseId());
        }
    
        @Override
        public List<PhaseId> getPhaseIds() {
            return Arrays.asList(PhaseId.APPLY_REQUEST_VALUES, PhaseId.RENDER_RESPONSE);
        }
    }  
    

    请注意,PhaseListener 方法在任何阶段之前和之后都被调用,但逻辑​​仅在所需阶段之前和之后处理。

    此外,请注意 MultiplePhasesListener 接口的实现使用 Java 8 中的默认方法。如果您使用较低的 Java 版本,则可以使用抽象类而不是接口并扩展该抽象类的 PhaseListener 实现。缺点是你不能再从另一个类扩展。

    【讨论】:

    • 感谢@Alex Fire 的回答。但正如您所说,“PhaseListener 方法在任何阶段之前和之后都被调用,但逻辑​​只在所需阶段之前和之后处理”。我的意图是为此实现一种方法,而无需在每个生命周期阶段调用方法的开销。
    猜你喜欢
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    相关资源
    最近更新 更多