JSF converter causes validator(s) to be ignored

前端 未结 2 848
孤独总比滥情好
孤独总比滥情好 2021-02-06 07:22

Here\'s the field:



        
2条回答
  •  太阳男子
    2021-02-06 08:12

    After reading BalusC's comment I am updating this post again.

    I created a small demo application and to see the phases and when the conversion and validation occur.

    View:

    
        
            
            
        
        
    
    

    Managed bean:

    @ManagedBean
    @SessionScoped
    public class DemoBean implements Serializable {
        private String field;
    
        public DemoBean() {
            System.out.println(Thread.currentThread().getStackTrace()[1]);
        }
    
        public String getField() {
            System.out.println(Thread.currentThread().getStackTrace()[1]);
            return field;
        }
    
        public void setField(String field) {
            System.out.println(Thread.currentThread().getStackTrace()[1]);
            this.field = field;
        }
    
        public String demoAxn() {
            System.out.println(Thread.currentThread().getStackTrace()[1]);
            return null;
        }
    }
    

    Converter:

    @FacesConverter(value="demoConverter")
    public class DemoConverter implements Converter {
    
        @Override
        public Object getAsObject(FacesContext context, UIComponent component, String value) {
            System.out.println(Thread.currentThread().getStackTrace()[1]);            
            return value;
        }
    
        @Override
        public String getAsString(FacesContext context, UIComponent component, Object value) {
            System.out.println(Thread.currentThread().getStackTrace()[1]);
            return (String) value;
        }    
    }
    

    Validator:

    @FacesValidator(value="demoValidator")
    public class DemoValidator implements Validator {
    
        @Override
        public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
            System.out.println(Thread.currentThread().getStackTrace()[1]);
        }
    
    }
    

    Phase listener:

    public class DemoPhaseListener implements PhaseListener {
        @Override
        public void afterPhase(PhaseEvent event) {
            System.out.println(Thread.currentThread().getStackTrace()[1]);
            System.out.println("PhaseId: " + event.getPhaseId() + "  ===============================\n\n");        
        }
    
        @Override
        public void beforePhase(PhaseEvent event) {
            System.out.println("\n\nPhaseId: " + event.getPhaseId() + "  ===============================");
            System.out.println(Thread.currentThread().getStackTrace()[1]);        
        }
    
        @Override
        public PhaseId getPhaseId() {
            return PhaseId.ANY_PHASE;
        }    
    }
    

    Registered the phase listener:

    
        pkg.DemoPhaseListener
    
    

    With that setting when the "Submit" button is clicked, the output is:

    INFO: PhaseId: RESTORE_VIEW 1  ===============================
    INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17)
    INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10)
    INFO: PhaseId: RESTORE_VIEW 1  ===============================
    
    INFO: PhaseId: APPLY_REQUEST_VALUES 2  ===============================
    INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17)
    INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10)
    INFO: PhaseId: APPLY_REQUEST_VALUES 2  ===============================
    
    INFO: PhaseId: PROCESS_VALIDATIONS 3  ===============================
    INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17)
    INFO: pkg.DemoConverter.getAsObject(DemoConverter.java:13)
    INFO: pkg.DemoValidator.validate(DemoValidator.java:14)
    INFO: pkg.DemoBean.getField(DemoBean.java:17)
    INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10)
    INFO: PhaseId: PROCESS_VALIDATIONS 3  ===============================
    
    INFO: PhaseId: UPDATE_MODEL_VALUES 4  ===============================
    INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17)
    INFO: pkg.DemoBean.setField(DemoBean.java:22)
    INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10)
    INFO: PhaseId: UPDATE_MODEL_VALUES 4  ===============================
    
    INFO: PhaseId: INVOKE_APPLICATION 5  ===============================
    INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17)
    INFO: pkg.DemoBean.demoAxn(DemoBean.java:27)
    INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10)
    INFO: PhaseId: INVOKE_APPLICATION 5  ===============================
    
    INFO: PhaseId: RENDER_RESPONSE 6  ===============================
    INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17)
    INFO: pkg.DemoBean.getField(DemoBean.java:17)
    INFO: pkg.DemoConverter.getAsString(DemoConverter.java:20)
    INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10)
    INFO: PhaseId: RENDER_RESPONSE 6  ===============================
    

    But when make change to throw a NPE in the converter as follows:

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        System.out.println(Thread.currentThread().getStackTrace()[1]);            
        throw new NullPointerException();
    }
    

    the output is:

    INFO: PhaseId: RESTORE_VIEW 1  ===============================
    INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17)
    INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10)
    INFO: PhaseId: RESTORE_VIEW 1  ===============================
    
    INFO: PhaseId: APPLY_REQUEST_VALUES 2  ===============================
    INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17)
    INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10)
    INFO: PhaseId: APPLY_REQUEST_VALUES 2  ===============================
    
    INFO: PhaseId: PROCESS_VALIDATIONS 3  ===============================
    INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17)
    INFO: pkg.DemoConverter.getAsObject(DemoConverter.java:13)
    INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10)
    INFO: PhaseId: PROCESS_VALIDATIONS 3  ===============================
    
    INFO: pkg.DemoBean.getField(DemoBean.java:17)
    

    But the stacktrace is displayed on the resulting view.

提交回复
热议问题