How do I instantiate bean properties in Jakarta Faces for future pages?

52 Views Asked by At

I am using Jakarta Faces 9.1 (Glassfish 7/TomEE). I have a page which, given a valid entry (bean.in1/UIInput), is used to generate text for a subsequent page entry (bean.in2/UIInput) which a user can then edit. When in1 and in2 are on the same page there is no problem. When in2 is on a subsequent page, I get "this.in2 is null" errors on the update() method.

I worked around this with a "rendered=false" (ie: hidden) for bean.in2/UIInput on the first page and a "rendered=true" for bean.in2/UIInput on the second subsequent page (as otherwise it would not show). I tried <f:view beforePhase="..." /> which prevents null errors but in2 is not updated in the subsequent page. The following minimal code shows the idea. The bean:

@Named
@SessionScoped
public class Bean1 implements Serializable {
    private UIInput in1;
    private UIInput in2;
    
    public void update() {
        // in1 is processed to produce in2 values:
        in2.setValue("Yo!!");
    }

    public UIInput getIn1() { return in1; }
    public void setIn1(UIInput in1) { this.in1 = in1; }

    public UIInput getIn2() { return in2; }
    public void setIn2(UIInput in2) { this.in2 = in2; }
}

The pages:

    <h:body>
        <div>Bakedbean testing</div>
        <h:form id="form0">
            <h:outputLabel for="rltd" value="Arbitrary input" />
            <h:inputText id="rltd"
                         binding="#{bean1.in1}"
                         valueChangeListener="#{bean1.update}"
                         immediate="true"
                         required="true">
            </h:inputText>
            <!-- This prevents in2 null errors -->
            <h:inputText id="in2" binding="#{bean1.in2}" rendered="false" />
        </h:form>
        <h:button id="next" value="Next" outcome="/next.xhtml" />
    </h:body>

    <h:body>
        <div>Next</div>
        <h:form id="next2">
            <h:outputLabel for="related">in2 instantiated?</h:outputLabel>
            <!-- This requires rendered as true because in2 is rendered as false on prev. page -->
            <p><h:inputTextarea id="related" style="border: 1px solid red;" rows="2" cols="25" rendered="true" binding="#{bean1.in2}"></h:inputTextarea></p>
        </h:form>
    </h:body>

This seems pretty hokey to me. Is there a way to instantiate in2 (even to "", avoiding null errors) as I believe managed-beans in faces-config in earlier versions used to allow? I have not found anything in Jakarta CDI documentation that gives me a clue.

UPDATE: I may have solved this by creating two beans where Bean1 is RequestScoped (and backs the 1st page) but also injects Bean2 which is SessionScoped and backs the 2nd page. Both beans use String instead of UIInput. Bean2 then updates the 2nd page inputTextArea value via a call in Bean1 (not binding). This obviates the hidden/rendered=true stuff. I'm hoping this solution does not run into memory or concurrency problems hence why I'm not adding this as a full answer.

0

There are 0 best solutions below