0

I was trying to see exactly how property injection works with ViewScoped beans.

I inject the List from One to Two without problem. When I try to inject the same List from Two to Three nothing is injected but I think that's the intended behavior (I might be wrong though).

However when I try to inject the selected value from the SelectOneMenu of Two into Three nothing is being injected.

Is there something I am missing or is that the normal behaviour? If so, how can I retrieve that value in Three?

One.java

@ManagedBean
@ViewScoped
public class One implements Serializable {

    private List<String> oneList;

    @PostConstruct
    void init() {
        setOneList(new ArrayList<String>());
        getOneList().add("aaa");
        getOneList().add("bbb");
        getOneList().add("ccc");
        getOneList().add("ddd");
    }

    //Getters + setters...
}

one.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="/WEB-INF/template.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
    <ui:define name="header">
        <h:outputText value="ONE" />
    </ui:define>
    <ui:define name="content">
        <h:form>
            <p:commandButton value="two" action="two" ajax="false" />
        </h:form>
    </ui:define>
</ui:composition>

Two.java

@ManagedBean
@ViewScoped
public class Two implements Serializable {

    @ManagedProperty("#{one.oneList}")
    private List<String> oneList;

    private String twoChoice;

    //Getter + setters...
}

two.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="/WEB-INF/template.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
    <ui:define name="header">
        <h:outputText value="TWO" />
    </ui:define>
    <ui:define name="content">
        <h:form>
            <p:selectOneMenu id="test" value="#{two.twoChoice}">
                <f:selectItems value="#{two.oneList}" />
            </p:selectOneMenu>
            <p:commandButton value="three" action="three" ajax="false" />
        </h:form>
    </ui:define>
</ui:composition>

Three.java

@ManagedBean
@ViewScoped
public class Three implements Serializable {
    @ManagedProperty("#{two.oneList}")
    private List<String> oneList;

    @ManagedProperty("#{two.twoChoice}")
    private String twoChoice;

    private String threeChoice;

    //Getters + setters...
}

three.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="/WEB-INF/template.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
    <ui:define name="header">
        <h:outputText value="THREE" />
    </ui:define>
    <ui:define name="content">
        <h:outputText value="#{three.twoChoice}" />
    </ui:define>
    <h:form>
        <p:selectOneMenu value="#{three.threeChoice}">
            <f:selectItems value="#{three.oneList}" />
        </p:selectOneMenu>
    </h:form>
</ui:composition>
noisegrrrl
  • 149
  • 1
  • 13

1 Answers1

4

Managed properties are not intended to work like that. Keep in mind that a @ViewScoped bean is designed to keep alive as long as the view doesn't change, which means at the moment you navigate from one page to another using the non-ajax command button (in fact you're specifying the navigation-case to go in the action attribute), they should be destroyed, so you can't get any value from them.

Normally, I use @ManagedProperty notation to inject broader scope values (for example, a session value in a view scoped bean). So what is the solution for your case?

Actually you have different options:

Community
  • 1
  • 1
Aritz
  • 30,971
  • 16
  • 136
  • 217
  • I'm trying not to use Session Scoped as I want my user to be able to work on different pages at the same time. How does flash scope works exactly? Are the variables stored in a session? – noisegrrrl Jul 23 '13 at 08:28
  • Not exactly. That scope is a JSF 2 introduced feature which is implemented by a map which survives a redirection, so you'll have them available for next view, but not for the next ones. In summary, it's something in the middle of the view and the session, so does not affect your session. However, as I mention above it's yet a bit buggy in Mojarra implementations. – Aritz Jul 23 '13 at 09:41