You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by "Joe Reger, Jr." <re...@gmail.com> on 2007/03/22 12:33:10 UTC

Flow from backing bean to page while also initializing second backing bean?

Hi.

I'm using MyFaces 1.1.5, Facelets 1.1.12, Java 6 and Tomcat 5.5.

1) page1.xhtml with backing bean Page1.java.  Page loads properly, displays
a form of some sort.

2) User types some info into page1.xhtml and hits "Save" which calls
Page1.save().

3) Page1.save() method returns a String.  JSF handles the page navigation
and redirection.

Problem: I can return "page2", to go to the second page in the flow.  But I
need to initialize the backing bean for page2.xhtml which is called
Page2.java.  If I simply use a faces-config.xml-defined navigation rule
("page2") I can't do this initialization... it'll call the page but won't
call any methods to initialize.  So page2.xhtml displays for the user but
they don't see the effect of the data they entered on page1.xhtml.

Constraint: Ajax4jsf only seems to work when I have a no-argument empty
constructor, so I can't do backing bean initialization there.

Question: In a commandLink I can specify #{page2.myInitMethod} (Facelets
processes the EL and tells JSF where to go) which allows me to initialize my
backing bean and return String "page2" so that the user gets the page.  But
I can't do that in step 3) above... the backing bean can only return a
String that's pre-defined in faces-config.xml.  Is there any way to route
the browser from a backing bean to another page while specifying an
initialization method?  Assuming I can't return "page2.myInitMethod".

Motivation: Slowly moving from a plain MyFaces implementation towards Seam
which requires no-argument empty constructors.  Also looking to get Ajax4Jsf
running on multi-screen wizard-like flows.  The app consists of about 50
backing beans and in the past I used java object constructors to initialize
the beans, load stuff from the database, etc.  I'm sure I'm missing some
basic page flow design pattern built into JSF and any help is appreciated.

Thanks,

Joe

Re: Flow from backing bean to page while also initializing second backing bean?

Posted by Mike Kienenberger <mk...@gmail.com>.
I think the biggest problem with using the constructor is that it only
gets triggered on the initial view.   It's not called if the object is
recreated while serialized.   That's what you're seeing now.   You
either need to save-state the initialized data, or you need to provide
initialization for both constructors and serialization read methods
methods.

I now always use savestate on everything that isn't a managed bean
property or an input value-binding.  For some beans, I have the last
managed property be "initialize" to let me set up some things.   These
two methods have handled everything I've needed.

In the past, I've used Spring and InitializingBean interface on my
page bean.  I've also used readObject(java.io.ObjectInputStream in) /
readResolve() at times in the past.


On 3/27/07, Joe Reger, Jr. <re...@gmail.com> wrote:
> Hi Mike!  Thanks.  That definitely works for my initial scenario.  But I
> hadn't considered the scenario of failed form validation on page2.  When
> that happens the creation of the backing bean is out of my control and JSF
> doesn't give me an easy way to initialize.
>
> And for all: I know this isn't a myfaces-specific issue... thanks for the
> help you can offer.
>
> So I'm reading this page:
> http://www.manning-sandbox.com/message.jspa?messageID=39573
>
> And I see that Kito Mann says "if your bean is request-scoped, all you have
> to do is load the data in its constructor."  Which is how I was doing it a
> while back.  I'd like to continue doing it this way but it violates "bean
> form" and will make it harder to move to Seam.  But how bad is using the
> constructor for initialization?  Does anybody on the list use constructors?
> Is it an issue for production scaling on multiple servers (say, with
> Tomcat's session replication)?
>
> Thanks to all for the ideas and input.
>
> Joe
>
>
> On 3/27/07, Mike Kienenberger <mk...@gmail.com> wrote:
> > Still seems to me like the easiest way to do this is with
> >
> > <uicommand action="#{ page.save}">
> >     <f:setPropertyActionListener
> target="#{page2.initialize}"
> > value="anything"/>
> >     <f:setPropertyActionListener
> target="#{page3.initialize}"
> > value="whatever"/>
> > </uicommand>
> >
> >
> > On 3/27/07, Joe Reger, Jr. <re...@gmail.com> wrote:
> > > Ok, so I got this to work by using this code in the first bean:
> > > SecondBean bean =
> > >
> (SecondBean)FacesContext.getCurrentInstance().getApplication().getVariableResolver().resolveVariable(FacesContext.getCurrentInstance(),
> > > "secondBean");
> > > return bean.beginView();
> > >
> > > It successfully initializes the second bean, allowing me to load stuff
> from
> > > the database, etc.   The problem is that when a field on that second
> form
> > > fails validation the JSF framework doesn't re-initialize the bean (or
> keep
> > > the values I loaded into it) so the app blows up. The bean is declared
> to
> > > the request scope.
> > >
> > > So now I'm faced with having to turn off all JSF validation (is that
> even
> > > possible?) and manually validating everything so that I can run an
> > > initialization method first.  And that'll likely be a problem because
> I'll
> > > overwrite the values set from the form.  So the phase listener is
> looking
> > > better but there's no way that I'm going to write one for each page in
> the
> > > app.  XML config, backing bean, xhtml page and phase listener just to
> create
> > > a page?  This is getting way out of control.
> > >
> > > It feels like I'm doing something structurally wrong... like I'm
> fighting
> > > the framework... but the demo apps I find out there all do it the same
> way
> > > and encounter the same issues as soon as you try to go beyond the basic
> > > scenario.
> > >
> > > I just don't understand how I can give control of my page-level beans to
> the
> > > framework and have dynamic page-level functionality that's anything more
> > > than very basic CRUD.
> > >
> > > Joe
> > >
> > >
> > >  On 3/22/07, David Delbecq < delbd@oma.be> wrote:
> > > > Mail quite confusing, i try to give partial answers anyway
> > > >
> > > > En l'instant précis du 22/03/07 12:33, Joe Reger, Jr. s'exprimait en
> ces
> > > > termes:
> > > > > Hi.
> > > > >
> > > > > I'm using MyFaces 1.1.5, Facelets 1.1.12, Java 6 and Tomcat 5.5.
> > > > >
> > > > > 1) page1.xhtml with backing bean Page1.java.  Page loads properly,
> > > > > displays a form of some sort.
> > > > >
> > > > > 2) User types some info into page1.xhtml and hits "Save" which calls
> > > > > Page1.save().
> > > > >
> > > > > 3) Page1.save() method returns a String.  JSF handles the page
> > > > > navigation and redirection.
> > > > >
> > > > > Problem: I can return "page2", to go to the second page in the flow.
> > > > > But I need to initialize the backing bean for page2.xhtml which is
> > > > > called Page2.java.  If I simply use a faces-config.xml-defined
> > > > > navigation rule ("page2") I can't do this initialization... it'll
> call
> > > > > the page but won't call any methods to initialize.  So page2.xhtml
> > > > > displays for the user but they don't see the effect of the data they
> > > > > entered on page1.xhtml .
> > > > you don't need a backing bean per page, if page1 and page2 share same
> > > > datas, why not use the same backing bean for both?
> > > > >
> > > > > Constraint: Ajax4jsf only seems to work when I have a no-argument
> > > > > empty constructor, so I can't do backing bean initialization there.
> > > > no-arguments constructor is indeed part of the definition of the bean
> > > > concept :). If your bean are session scoped, they must be moreover
> > > > serializable. A class can only be serializable if it has a no argument
> > > > constructor.
> > > > >
> > > > > Question: In a commandLink I can specify #{page2.myInitMethod }
> > > > > (Facelets processes the EL and tells JSF where to go) which allows
> me
> > > > > to initialize my backing bean and return String "page2" so that the
> > > > > user gets the page.  But I can't do that in step 3) above... the
> > > > > backing bean can only return a String that's pre-defined in
> > > > > faces-config.xml.  Is there any way to route the browser from a
> > > > > backing bean to another page while specifying an initialization
> > > > > method?  Assuming I can't return " page2.myInitMethod".
> > > > Let JSF do the initialization stuff itself based on bean definitions
> > > > made in faces-config.xml. Btw, you can use managed properties if you
> > > > want you bean to know about each other. JSF does all this by itself
> > > > Example (myRequestBean.getOtherBean() will now return a JSF session
> > > > scoped managed bean):
> > > >         <managed-bean>
> > > >
> > > <managed-bean-name>myRequestBean</managed-bean-name>
> > > >
> > > > <managed-bean-class> com.company.SomeBean</managed-bean-class>
> > > >
> > > <managed-bean-scope>request</managed-bean-scope>
> > > >                 <managed-property>
> > > >
> > > <property-name>otherBean</property-name>
> > > >
> > > > <property-class>com.company.SomeOtherBean</property-class>
> > > >                      <value>#{mySessionBean}</value>
> > > >                  </managed-property>
> > > >         </managed-bean>
> > > >         <managed-bean>
> > > >
> > > <managed-bean-name>mySessionBean</managed-bean-name>
> > > >
> > > > <managed-bean-class>com.company.SomeOtherBean</managed-bean-class>
> > > >
> > > <managed-bean-scope>session</managed-bean-scope>
> > > >         </managed-bean>
> > > >
> > > > Moreover, again, you can make page1.java and page2.java a single bean.
> > > > Or you can have page1.java have a getter returning page2. In
> page2.xhtml
> > > > EL would then look like #{ page1.page2.someProperty }
> > > > >
> > > > > Motivation: Slowly moving from a plain MyFaces implementation
> towards
> > > > > Seam which requires no-argument empty constructors.  Also looking to
> > > > > get Ajax4Jsf running on multi-screen wizard-like flows.  The app
> > > > > consists of about 50 backing beans and in the past I used java
> object
> > > > > constructors to initialize the beans, load stuff from the database,
> > > > > etc.  I'm sure I'm missing some basic page flow design pattern built
> > > > > into JSF and any help is appreciated.
> > > > >
> > > > I think you are stuck thinking you need a managed bean per form/page.
> A
> > > > JSF Managed bean is simply a bean that has a life duration (depending
> on
> > > > it's scope) and is made available to JSF component using EL
> expression.
> > > > The structure of your bean and their relation does not have to be tied
> > > > to your form. A form can combine several beans or a bean can be used
> by
> > > > several forms. Also, only beans you want directly available as EL
> value
> > > > need to be JSF managed. Objects returned by a getter of a JSF managed
> > > > bean do not need to be JSF managed.
> > > > > Thanks,
> > > > >
> > > > > Joe
> > > >
> > > >
> > >
> > >
> >
>
>

Re: Flow from backing bean to page while also initializing second backing bean?

Posted by "Joe Reger, Jr." <re...@gmail.com>.
Hi Mike!  Thanks.  That definitely works for my initial scenario.  But I
hadn't considered the scenario of failed form validation on page2.  When
that happens the creation of the backing bean is out of my control and JSF
doesn't give me an easy way to initialize.

And for all: I know this isn't a myfaces-specific issue... thanks for the
help you can offer.

So I'm reading this page:
http://www.manning-sandbox.com/message.jspa?messageID=39573

And I see that Kito Mann says "if your bean is request-scoped, all you have
to do is load the data in its constructor."  Which is how I was doing it a
while back.  I'd like to continue doing it this way but it violates "bean
form" and will make it harder to move to Seam.  But how bad is using the
constructor for initialization?  Does anybody on the list use constructors?
Is it an issue for production scaling on multiple servers (say, with
Tomcat's session replication)?

Thanks to all for the ideas and input.

Joe

On 3/27/07, Mike Kienenberger <mk...@gmail.com> wrote:
>
> Still seems to me like the easiest way to do this is with
>
> <uicommand action="#{page.save}">
>     <f:setPropertyActionListener  target="#{page2.initialize}"
> value="anything"/>
>     <f:setPropertyActionListener  target="#{page3.initialize}"
> value="whatever"/>
> </uicommand>
>
>
> On 3/27/07, Joe Reger, Jr. <re...@gmail.com> wrote:
> > Ok, so I got this to work by using this code in the first bean:
> > SecondBean bean =
> >
> (SecondBean)FacesContext.getCurrentInstance().getApplication().getVariableResolver().resolveVariable(
> FacesContext.getCurrentInstance(),
> > "secondBean");
> > return bean.beginView();
> >
> > It successfully initializes the second bean, allowing me to load stuff
> from
> > the database, etc.   The problem is that when a field on that second
> form
> > fails validation the JSF framework doesn't re-initialize the bean (or
> keep
> > the values I loaded into it) so the app blows up. The bean is declared
> to
> > the request scope.
> >
> > So now I'm faced with having to turn off all JSF validation (is that
> even
> > possible?) and manually validating everything so that I can run an
> > initialization method first.  And that'll likely be a problem because
> I'll
> > overwrite the values set from the form.  So the phase listener is
> looking
> > better but there's no way that I'm going to write one for each page in
> the
> > app.  XML config, backing bean, xhtml page and phase listener just to
> create
> > a page?  This is getting way out of control.
> >
> > It feels like I'm doing something structurally wrong... like I'm
> fighting
> > the framework... but the demo apps I find out there all do it the same
> way
> > and encounter the same issues as soon as you try to go beyond the basic
> > scenario.
> >
> > I just don't understand how I can give control of my page-level beans to
> the
> > framework and have dynamic page-level functionality that's anything more
> > than very basic CRUD.
> >
> > Joe
> >
> >
> >  On 3/22/07, David Delbecq <de...@oma.be> wrote:
> > > Mail quite confusing, i try to give partial answers anyway
> > >
> > > En l'instant précis du 22/03/07 12:33, Joe Reger, Jr. s'exprimait en
> ces
> > > termes:
> > > > Hi.
> > > >
> > > > I'm using MyFaces 1.1.5, Facelets 1.1.12, Java 6 and Tomcat 5.5.
> > > >
> > > > 1) page1.xhtml with backing bean Page1.java.  Page loads properly,
> > > > displays a form of some sort.
> > > >
> > > > 2) User types some info into page1.xhtml and hits "Save" which calls
> > > > Page1.save().
> > > >
> > > > 3) Page1.save() method returns a String.  JSF handles the page
> > > > navigation and redirection.
> > > >
> > > > Problem: I can return "page2", to go to the second page in the flow.
> > > > But I need to initialize the backing bean for page2.xhtml which is
> > > > called Page2.java.  If I simply use a faces-config.xml-defined
> > > > navigation rule ("page2") I can't do this initialization... it'll
> call
> > > > the page but won't call any methods to initialize.  So page2.xhtml
> > > > displays for the user but they don't see the effect of the data they
> > > > entered on page1.xhtml.
> > > you don't need a backing bean per page, if page1 and page2 share same
> > > datas, why not use the same backing bean for both?
> > > >
> > > > Constraint: Ajax4jsf only seems to work when I have a no-argument
> > > > empty constructor, so I can't do backing bean initialization there.
> > > no-arguments constructor is indeed part of the definition of the bean
> > > concept :). If your bean are session scoped, they must be moreover
> > > serializable. A class can only be serializable if it has a no argument
> > > constructor.
> > > >
> > > > Question: In a commandLink I can specify #{page2.myInitMethod }
> > > > (Facelets processes the EL and tells JSF where to go) which allows
> me
> > > > to initialize my backing bean and return String "page2" so that the
> > > > user gets the page.  But I can't do that in step 3) above... the
> > > > backing bean can only return a String that's pre-defined in
> > > > faces-config.xml.  Is there any way to route the browser from a
> > > > backing bean to another page while specifying an initialization
> > > > method?  Assuming I can't return " page2.myInitMethod".
> > > Let JSF do the initialization stuff itself based on bean definitions
> > > made in faces-config.xml. Btw, you can use managed properties if you
> > > want you bean to know about each other. JSF does all this by itself
> > > Example (myRequestBean.getOtherBean() will now return a JSF session
> > > scoped managed bean):
> > >         <managed-bean>
> > >
> > <managed-bean-name>myRequestBean</managed-bean-name>
> > >
> > > <managed-bean-class> com.company.SomeBean</managed-bean-class>
> > >
> > <managed-bean-scope>request</managed-bean-scope>
> > >                 <managed-property>
> > >
> > <property-name>otherBean</property-name>
> > >
> > > <property-class>com.company.SomeOtherBean</property-class>
> > >                      <value>#{mySessionBean}</value>
> > >                  </managed-property>
> > >         </managed-bean>
> > >         <managed-bean>
> > >
> > <managed-bean-name>mySessionBean</managed-bean-name>
> > >
> > > <managed-bean-class>com.company.SomeOtherBean</managed-bean-class>
> > >
> > <managed-bean-scope>session</managed-bean-scope>
> > >         </managed-bean>
> > >
> > > Moreover, again, you can make page1.java and page2.java a single bean.
> > > Or you can have page1.java have a getter returning page2. In
> page2.xhtml
> > > EL would then look like #{page1.page2.someProperty }
> > > >
> > > > Motivation: Slowly moving from a plain MyFaces implementation
> towards
> > > > Seam which requires no-argument empty constructors.  Also looking to
> > > > get Ajax4Jsf running on multi-screen wizard-like flows.  The app
> > > > consists of about 50 backing beans and in the past I used java
> object
> > > > constructors to initialize the beans, load stuff from the database,
> > > > etc.  I'm sure I'm missing some basic page flow design pattern built
> > > > into JSF and any help is appreciated.
> > > >
> > > I think you are stuck thinking you need a managed bean per form/page.
> A
> > > JSF Managed bean is simply a bean that has a life duration (depending
> on
> > > it's scope) and is made available to JSF component using EL
> expression.
> > > The structure of your bean and their relation does not have to be tied
> > > to your form. A form can combine several beans or a bean can be used
> by
> > > several forms. Also, only beans you want directly available as EL
> value
> > > need to be JSF managed. Objects returned by a getter of a JSF managed
> > > bean do not need to be JSF managed.
> > > > Thanks,
> > > >
> > > > Joe
> > >
> > >
> >
> >
>

Re: Flow from backing bean to page while also initializing second backing bean?

Posted by Mike Kienenberger <mk...@gmail.com>.
Still seems to me like the easiest way to do this is with

<uicommand action="#{page.save}">
    <f:setPropertyActionListener  target="#{page2.initialize}"
value="anything"/>
    <f:setPropertyActionListener  target="#{page3.initialize}"
value="whatever"/>
</uicommand>


On 3/27/07, Joe Reger, Jr. <re...@gmail.com> wrote:
> Ok, so I got this to work by using this code in the first bean:
> SecondBean bean =
> (SecondBean)FacesContext.getCurrentInstance().getApplication().getVariableResolver().resolveVariable(FacesContext.getCurrentInstance(),
> "secondBean");
> return bean.beginView();
>
> It successfully initializes the second bean, allowing me to load stuff from
> the database, etc.   The problem is that when a field on that second form
> fails validation the JSF framework doesn't re-initialize the bean (or keep
> the values I loaded into it) so the app blows up. The bean is declared to
> the request scope.
>
> So now I'm faced with having to turn off all JSF validation (is that even
> possible?) and manually validating everything so that I can run an
> initialization method first.  And that'll likely be a problem because I'll
> overwrite the values set from the form.  So the phase listener is looking
> better but there's no way that I'm going to write one for each page in the
> app.  XML config, backing bean, xhtml page and phase listener just to create
> a page?  This is getting way out of control.
>
> It feels like I'm doing something structurally wrong... like I'm fighting
> the framework... but the demo apps I find out there all do it the same way
> and encounter the same issues as soon as you try to go beyond the basic
> scenario.
>
> I just don't understand how I can give control of my page-level beans to the
> framework and have dynamic page-level functionality that's anything more
> than very basic CRUD.
>
> Joe
>
>
>  On 3/22/07, David Delbecq <de...@oma.be> wrote:
> > Mail quite confusing, i try to give partial answers anyway
> >
> > En l'instant précis du 22/03/07 12:33, Joe Reger, Jr. s'exprimait en ces
> > termes:
> > > Hi.
> > >
> > > I'm using MyFaces 1.1.5, Facelets 1.1.12, Java 6 and Tomcat 5.5.
> > >
> > > 1) page1.xhtml with backing bean Page1.java.  Page loads properly,
> > > displays a form of some sort.
> > >
> > > 2) User types some info into page1.xhtml and hits "Save" which calls
> > > Page1.save().
> > >
> > > 3) Page1.save() method returns a String.  JSF handles the page
> > > navigation and redirection.
> > >
> > > Problem: I can return "page2", to go to the second page in the flow.
> > > But I need to initialize the backing bean for page2.xhtml which is
> > > called Page2.java.  If I simply use a faces-config.xml-defined
> > > navigation rule ("page2") I can't do this initialization... it'll call
> > > the page but won't call any methods to initialize.  So page2.xhtml
> > > displays for the user but they don't see the effect of the data they
> > > entered on page1.xhtml.
> > you don't need a backing bean per page, if page1 and page2 share same
> > datas, why not use the same backing bean for both?
> > >
> > > Constraint: Ajax4jsf only seems to work when I have a no-argument
> > > empty constructor, so I can't do backing bean initialization there.
> > no-arguments constructor is indeed part of the definition of the bean
> > concept :). If your bean are session scoped, they must be moreover
> > serializable. A class can only be serializable if it has a no argument
> > constructor.
> > >
> > > Question: In a commandLink I can specify #{page2.myInitMethod }
> > > (Facelets processes the EL and tells JSF where to go) which allows me
> > > to initialize my backing bean and return String "page2" so that the
> > > user gets the page.  But I can't do that in step 3) above... the
> > > backing bean can only return a String that's pre-defined in
> > > faces-config.xml.  Is there any way to route the browser from a
> > > backing bean to another page while specifying an initialization
> > > method?  Assuming I can't return " page2.myInitMethod".
> > Let JSF do the initialization stuff itself based on bean definitions
> > made in faces-config.xml. Btw, you can use managed properties if you
> > want you bean to know about each other. JSF does all this by itself
> > Example (myRequestBean.getOtherBean() will now return a JSF session
> > scoped managed bean):
> >         <managed-bean>
> >
> <managed-bean-name>myRequestBean</managed-bean-name>
> >
> > <managed-bean-class> com.company.SomeBean</managed-bean-class>
> >
> <managed-bean-scope>request</managed-bean-scope>
> >                 <managed-property>
> >
> <property-name>otherBean</property-name>
> >
> > <property-class>com.company.SomeOtherBean</property-class>
> >                      <value>#{mySessionBean}</value>
> >                  </managed-property>
> >         </managed-bean>
> >         <managed-bean>
> >
> <managed-bean-name>mySessionBean</managed-bean-name>
> >
> > <managed-bean-class>com.company.SomeOtherBean</managed-bean-class>
> >
> <managed-bean-scope>session</managed-bean-scope>
> >         </managed-bean>
> >
> > Moreover, again, you can make page1.java and page2.java a single bean.
> > Or you can have page1.java have a getter returning page2. In page2.xhtml
> > EL would then look like #{page1.page2.someProperty }
> > >
> > > Motivation: Slowly moving from a plain MyFaces implementation towards
> > > Seam which requires no-argument empty constructors.  Also looking to
> > > get Ajax4Jsf running on multi-screen wizard-like flows.  The app
> > > consists of about 50 backing beans and in the past I used java object
> > > constructors to initialize the beans, load stuff from the database,
> > > etc.  I'm sure I'm missing some basic page flow design pattern built
> > > into JSF and any help is appreciated.
> > >
> > I think you are stuck thinking you need a managed bean per form/page. A
> > JSF Managed bean is simply a bean that has a life duration (depending on
> > it's scope) and is made available to JSF component using EL expression.
> > The structure of your bean and their relation does not have to be tied
> > to your form. A form can combine several beans or a bean can be used by
> > several forms. Also, only beans you want directly available as EL value
> > need to be JSF managed. Objects returned by a getter of a JSF managed
> > bean do not need to be JSF managed.
> > > Thanks,
> > >
> > > Joe
> >
> >
>
>

Re: Flow from backing bean to page while also initializing second backing bean?

Posted by "Joe Reger, Jr." <re...@gmail.com>.
Ok, so I got this to work by using this code in the first bean:
SecondBean bean =
(SecondBean)FacesContext.getCurrentInstance().getApplication().getVariableResolver().resolveVariable(
FacesContext.getCurrentInstance(), "secondBean");
return bean.beginView();

It successfully initializes the second bean, allowing me to load stuff from
the database, etc.   The problem is that when a field on that second form
fails validation the JSF framework doesn't re-initialize the bean (or keep
the values I loaded into it) so the app blows up. The bean is declared to
the request scope.

So now I'm faced with having to turn off all JSF validation (is that even
possible?) and manually validating everything so that I can run an
initialization method first.  And that'll likely be a problem because I'll
overwrite the values set from the form.  So the phase listener is looking
better but there's no way that I'm going to write one for each page in the
app.  XML config, backing bean, xhtml page and phase listener just to create
a page?  This is getting way out of control.

It feels like I'm doing something structurally wrong... like I'm fighting
the framework... but the demo apps I find out there all do it the same way
and encounter the same issues as soon as you try to go beyond the basic
scenario.

I just don't understand how I can give control of my page-level beans to the
framework and have dynamic page-level functionality that's anything more
than very basic CRUD.

Joe

On 3/22/07, David Delbecq <de...@oma.be> wrote:
>
> Mail quite confusing, i try to give partial answers anyway
>
> En l'instant précis du 22/03/07 12:33, Joe Reger, Jr. s'exprimait en ces
> termes:
> > Hi.
> >
> > I'm using MyFaces 1.1.5, Facelets 1.1.12, Java 6 and Tomcat 5.5.
> >
> > 1) page1.xhtml with backing bean Page1.java.  Page loads properly,
> > displays a form of some sort.
> >
> > 2) User types some info into page1.xhtml and hits "Save" which calls
> > Page1.save().
> >
> > 3) Page1.save() method returns a String.  JSF handles the page
> > navigation and redirection.
> >
> > Problem: I can return "page2", to go to the second page in the flow.
> > But I need to initialize the backing bean for page2.xhtml which is
> > called Page2.java.  If I simply use a faces-config.xml-defined
> > navigation rule ("page2") I can't do this initialization... it'll call
> > the page but won't call any methods to initialize.  So page2.xhtml
> > displays for the user but they don't see the effect of the data they
> > entered on page1.xhtml.
> you don't need a backing bean per page, if page1 and page2 share same
> datas, why not use the same backing bean for both?
> >
> > Constraint: Ajax4jsf only seems to work when I have a no-argument
> > empty constructor, so I can't do backing bean initialization there.
> no-arguments constructor is indeed part of the definition of the bean
> concept :). If your bean are session scoped, they must be moreover
> serializable. A class can only be serializable if it has a no argument
> constructor.
> >
> > Question: In a commandLink I can specify #{page2.myInitMethod}
> > (Facelets processes the EL and tells JSF where to go) which allows me
> > to initialize my backing bean and return String "page2" so that the
> > user gets the page.  But I can't do that in step 3) above... the
> > backing bean can only return a String that's pre-defined in
> > faces-config.xml.  Is there any way to route the browser from a
> > backing bean to another page while specifying an initialization
> > method?  Assuming I can't return "page2.myInitMethod".
> Let JSF do the initialization stuff itself based on bean definitions
> made in faces-config.xml. Btw, you can use managed properties if you
> want you bean to know about each other. JSF does all this by itself
> Example (myRequestBean.getOtherBean() will now return a JSF session
> scoped managed bean):
>         <managed-bean>
>                 <managed-bean-name>myRequestBean</managed-bean-name>
>
> <managed-bean-class>com.company.SomeBean</managed-bean-class>
>                 <managed-bean-scope>request</managed-bean-scope>
>                 <managed-property>
>                      <property-name>otherBean</property-name>
>
> <property-class>com.company.SomeOtherBean</property-class>
>                      <value>#{mySessionBean}</value>
>                  </managed-property>
>         </managed-bean>
>         <managed-bean>
>                 <managed-bean-name>mySessionBean</managed-bean-name>
>
> <managed-bean-class>com.company.SomeOtherBean</managed-bean-class>
>                 <managed-bean-scope>session</managed-bean-scope>
>         </managed-bean>
>
> Moreover, again, you can make page1.java and page2.java a single bean.
> Or you can have page1.java have a getter returning page2. In page2.xhtml
> EL would then look like #{page1.page2.someProperty}
> >
> > Motivation: Slowly moving from a plain MyFaces implementation towards
> > Seam which requires no-argument empty constructors.  Also looking to
> > get Ajax4Jsf running on multi-screen wizard-like flows.  The app
> > consists of about 50 backing beans and in the past I used java object
> > constructors to initialize the beans, load stuff from the database,
> > etc.  I'm sure I'm missing some basic page flow design pattern built
> > into JSF and any help is appreciated.
> >
> I think you are stuck thinking you need a managed bean per form/page. A
> JSF Managed bean is simply a bean that has a life duration (depending on
> it's scope) and is made available to JSF component using EL expression.
> The structure of your bean and their relation does not have to be tied
> to your form. A form can combine several beans or a bean can be used by
> several forms. Also, only beans you want directly available as EL value
> need to be JSF managed. Objects returned by a getter of a JSF managed
> bean do not need to be JSF managed.
> > Thanks,
> >
> > Joe
>
>

Re: Flow from backing bean to page while also initializing second backing bean?

Posted by David Delbecq <de...@oma.be>.
Mail quite confusing, i try to give partial answers anyway

En l'instant précis du 22/03/07 12:33, Joe Reger, Jr. s'exprimait en ces
termes:
> Hi.
>
> I'm using MyFaces 1.1.5, Facelets 1.1.12, Java 6 and Tomcat 5.5.
>
> 1) page1.xhtml with backing bean Page1.java.  Page loads properly,
> displays a form of some sort.
>
> 2) User types some info into page1.xhtml and hits "Save" which calls
> Page1.save().
>
> 3) Page1.save() method returns a String.  JSF handles the page
> navigation and redirection.
>
> Problem: I can return "page2", to go to the second page in the flow. 
> But I need to initialize the backing bean for page2.xhtml which is
> called Page2.java.  If I simply use a faces-config.xml-defined
> navigation rule ("page2") I can't do this initialization... it'll call
> the page but won't call any methods to initialize.  So page2.xhtml
> displays for the user but they don't see the effect of the data they
> entered on page1.xhtml.
you don't need a backing bean per page, if page1 and page2 share same
datas, why not use the same backing bean for both?
>
> Constraint: Ajax4jsf only seems to work when I have a no-argument
> empty constructor, so I can't do backing bean initialization there.
no-arguments constructor is indeed part of the definition of the bean
concept :). If your bean are session scoped, they must be moreover
serializable. A class can only be serializable if it has a no argument
constructor.
>
> Question: In a commandLink I can specify #{page2.myInitMethod}
> (Facelets processes the EL and tells JSF where to go) which allows me
> to initialize my backing bean and return String "page2" so that the
> user gets the page.  But I can't do that in step 3) above... the
> backing bean can only return a String that's pre-defined in
> faces-config.xml.  Is there any way to route the browser from a
> backing bean to another page while specifying an initialization
> method?  Assuming I can't return "page2.myInitMethod".
Let JSF do the initialization stuff itself based on bean definitions
made in faces-config.xml. Btw, you can use managed properties if you
want you bean to know about each other. JSF does all this by itself
Example (myRequestBean.getOtherBean() will now return a JSF session
scoped managed bean):
        <managed-bean>
                <managed-bean-name>myRequestBean</managed-bean-name>
               
<managed-bean-class>com.company.SomeBean</managed-bean-class>
                <managed-bean-scope>request</managed-bean-scope>
                <managed-property>
                     <property-name>otherBean</property-name>
                    
<property-class>com.company.SomeOtherBean</property-class>
                     <value>#{mySessionBean}</value>
                 </managed-property>
        </managed-bean>
        <managed-bean>
                <managed-bean-name>mySessionBean</managed-bean-name>
               
<managed-bean-class>com.company.SomeOtherBean</managed-bean-class>
                <managed-bean-scope>session</managed-bean-scope>
        </managed-bean>

Moreover, again, you can make page1.java and page2.java a single bean.
Or you can have page1.java have a getter returning page2. In page2.xhtml
EL would then look like #{page1.page2.someProperty}
>
> Motivation: Slowly moving from a plain MyFaces implementation towards
> Seam which requires no-argument empty constructors.  Also looking to
> get Ajax4Jsf running on multi-screen wizard-like flows.  The app
> consists of about 50 backing beans and in the past I used java object
> constructors to initialize the beans, load stuff from the database,
> etc.  I'm sure I'm missing some basic page flow design pattern built
> into JSF and any help is appreciated.
>
I think you are stuck thinking you need a managed bean per form/page. A
JSF Managed bean is simply a bean that has a life duration (depending on
it's scope) and is made available to JSF component using EL expression.
The structure of your bean and their relation does not have to be tied
to your form. A form can combine several beans or a bean can be used by
several forms. Also, only beans you want directly available as EL value
need to be JSF managed. Objects returned by a getter of a JSF managed
bean do not need to be JSF managed.
> Thanks,
>
> Joe


Re: Flow from backing bean to page while also initializing second backing bean?

Posted by Mike Kienenberger <mk...@gmail.com>.
I generally use the t:updateActionListener approach.   Note that since
you're using facelets 1.1.12, it makes more sense to use
f:setPropertyActionListener -- this is a standard in JSF 1.2 and
facelets, and setPropertyActionListener works better in facelets than
most t:updateActionListener implementations.

You can have as many setPropertyActionListeners as you need, you can
have different initialization based on the calling page, and you don't
need any additional dependencies.


On 3/22/07, Werner Punz <we...@gmail.com> wrote:
> pass the values needed from page1 to page2
> (via: t:updateActionListener is probably the easiest way=
> and then use the view controllers callbacks to preload the data
> according to your state)


On 3/22/07, Joe Reger, Jr. <re...@gmail.com> wrote:
> Hi.
>
> I'm using MyFaces 1.1.5, Facelets 1.1.12, Java 6 and Tomcat 5.5.
>
> 1) page1.xhtml with backing bean Page1.java.  Page loads properly, displays
> a form of some sort.
>
> 2) User types some info into page1.xhtml and hits "Save" which calls
> Page1.save().
>
> 3) Page1.save() method returns a String.  JSF handles the page navigation
> and redirection.
>
> Problem: I can return "page2", to go to the second page in the flow.  But I
> need to initialize the backing bean for page2.xhtml which is called
> Page2.java.  If I simply use a faces-config.xml-defined navigation rule
> ("page2") I can't do this initialization... it'll call the page but won't
> call any methods to initialize.  So page2.xhtml displays for the user but
> they don't see the effect of the data they entered on page1.xhtml.
>
> Constraint: Ajax4jsf only seems to work when I have a no-argument empty
> constructor, so I can't do backing bean initialization there.
>
> Question: In a commandLink I can specify #{page2.myInitMethod} (Facelets
> processes the EL and tells JSF where to go) which allows me to initialize my
> backing bean and return String "page2" so that the user gets the page.  But
> I can't do that in step 3) above... the backing bean can only return a
> String that's pre-defined in faces-config.xml.  Is there any way to route
> the browser from a backing bean to another page while specifying an
> initialization method?  Assuming I can't return "page2.myInitMethod".
>
> Motivation: Slowly moving from a plain MyFaces implementation towards Seam
> which requires no-argument empty constructors.  Also looking to get Ajax4Jsf
> running on multi-screen wizard-like flows.  The app consists of about 50
> backing beans and in the past I used java object constructors to initialize
> the beans, load stuff from the database, etc.  I'm sure I'm missing some
> basic page flow design pattern built into JSF and any help is appreciated.
>
> Thanks,
>
> Joe
>

Re: Flow from backing bean to page while also initializing second backing bean?

Posted by Volker Weber <v....@inexso.de>.
Hi,

> situations it makes more sense to have separate beans.  I'm surprised that
> there's no way to call custom initializers. In EJB there's a @PostConstruct
> annotation that calls custom logic after the bean manager creates the bean.

not realy a custom initializer, but according to the spec the managed
properties are set in the order they appear in the config. so you can
add a dummy property as the last one which does the initialization.

e.g.:

<managed-bean>
     ...
     <managed-property>
      <property-name>init</property-name>
      <value>true</value>
    </managed-property>
</managed-bean>

public void setInit(String dummy) {
  // call init method
  init();
}

this is what we do if needed.

Regards,
  Volker

Re: Flow from backing bean to page while also initializing second backing bean?

Posted by Werner Punz <we...@gmail.com>.
> 
>>> Let JSF do the initialization stuff itself based on bean definitions
> made in faces-config.xml.
> 
> This doesn't allow me to specify a method call on Page2.java to run my
> custom initialization logic.  Yes, on page2.xhtml I would be able to
> access properties from Page1.java but this isn't what I'm looking for. 
> I need to load other stuff in page2.xhtml based on data from page1.xhtml.
> 
>>> A form can combine several beans or a bean can be used by
> several forms.
> 
> Agreed.  And have used this numerous times in the app.  But in a few
> situations it makes more sense to have separate beans.  I'm surprised
> that there's no way to call custom initializers. In EJB there's a
> @PostConstruct annotation that calls custom logic after the bean manager
> creates the bean.
> 
> Thanks for the ideas and help.  Based on what you're saying it sounds
> like there's no way to do what I'm looking to do?
> 
> Later,
> 
Ok sorry, I was not reading the thread fully, but what you want to do is
to display
data being loaded from a db on a page 2 depending on some states being
passed down from page 1....

There are several ways to do this...
Either go for a scoping system (aka one bean per multiple pages, which
you obviously want to avoid)... which keeps
the bean in the backend stateful, so everything you do in page1 is
accessible in page2, you then can use various mechanisms to locate the
state that page2 has been reached
(the easiest one probably simply is to misuse the setters which are
called very early, or you could write a phase listener triggering into
your bean etc...)

whatever, once you are in page2 you can reuse the values according to
the state.


Another solution:
Use a simple view controller pattern (I really can recommend shale view
controllers here, they give you the initial callbacks you need for a
proper resolution, it delivers exactly the callbacks you said jsf was in
need for, and I agree here with you 100%)

pass the values needed from page1 to page2
(via: t:updateActionListener is probably the easiest way=
and then use the view controllers callbacks to preload the data
according to your state)



Third solution, use a dialog system like shale or some scoping or flash
system (savestate for instance)
to keep the values you need to pass from page1 to page2
then you have the values available in page2 as well
(probably savestate might be the easiest solution for this simple case)
You still can use the view controllers for the defined page callbacks
only the data which is passed from page1 to page2 has to be scoped.

This runs like:
run into the action, change the values on the savestated bean manually
you want to set, then return the outcome, in page2 get the bean again
via the variable resolver and then the values are available again.

Alternatively you could use dialog systems as well to pass the values.
(Shale dialog for instance has an object holer map which you can use)


there are numerous other solutions to this problem but those probably
are the ones which work best.



Re: Flow from backing bean to page while also initializing second backing bean?

Posted by Jeff Bischoff <jb...@klkurz.com>.
Joe,

It is possible. I replied to you on facelets list. Look at combining the 
code I provided with Werner's third solution. That should give you full 
control...

Joe Reger, Jr. wrote:
> Thanks for the ideas and help.  Based on what you're saying it sounds like
> there's no way to do what I'm looking to do?
> 
> Later,
> 
> Joe
> 




Re: Flow from backing bean to page while also initializing second backing bean?

Posted by "Joe Reger, Jr." <re...@gmail.com>.
>> you don't need a backing bean per page, if page1 and page2 share same
datas, why not use the same backing bean for both?

I understand.  They don't necessarily share the same data.  They're
dependent on some common data but perform separate functions.  The use case
I'm describing shouldn't be that abnormal.

>> no-arguments constructor is indeed part of the definition of the bean
concept :). If your bean are session scoped, they must be moreover
serializable. A class can only be serializable if it has a no argument
constructor.

I understand.  So how does JSF allow me to initialize my beans with custom
logic (call database, etc) when I am sending a user from page1.xhtml to
page2.xhtml after calling a method on Page1.java (which must return a
String)?

>> Let JSF do the initialization stuff itself based on bean definitions made
in faces-config.xml.

This doesn't allow me to specify a method call on Page2.java to run my
custom initialization logic.  Yes, on page2.xhtml I would be able to access
properties from Page1.java but this isn't what I'm looking for.  I need to
load other stuff in page2.xhtml based on data from page1.xhtml.

>> A form can combine several beans or a bean can be used by
several forms.

Agreed.  And have used this numerous times in the app.  But in a few
situations it makes more sense to have separate beans.  I'm surprised that
there's no way to call custom initializers. In EJB there's a @PostConstruct
annotation that calls custom logic after the bean manager creates the bean.

Thanks for the ideas and help.  Based on what you're saying it sounds like
there's no way to do what I'm looking to do?

Later,

Joe

Re: Flow from backing bean to page while also initializing second backing bean?

Posted by David Delbecq <de...@oma.be>.
Mail quite confusing, i try to give partial answers anyway

En l'instant précis du 22/03/07 12:33, Joe Reger, Jr. s'exprimait en ces
termes:
> Hi.
>
> I'm using MyFaces 1.1.5, Facelets 1.1.12, Java 6 and Tomcat 5.5.
>
> 1) page1.xhtml with backing bean Page1.java.  Page loads properly,
> displays a form of some sort.
>
> 2) User types some info into page1.xhtml and hits "Save" which calls
> Page1.save().
>
> 3) Page1.save() method returns a String.  JSF handles the page
> navigation and redirection.
>
> Problem: I can return "page2", to go to the second page in the flow. 
> But I need to initialize the backing bean for page2.xhtml which is
> called Page2.java.  If I simply use a faces-config.xml-defined
> navigation rule ("page2") I can't do this initialization... it'll call
> the page but won't call any methods to initialize.  So page2.xhtml
> displays for the user but they don't see the effect of the data they
> entered on page1.xhtml.
you don't need a backing bean per page, if page1 and page2 share same
datas, why not use the same backing bean for both?
>
> Constraint: Ajax4jsf only seems to work when I have a no-argument
> empty constructor, so I can't do backing bean initialization there.
no-arguments constructor is indeed part of the definition of the bean
concept :). If your bean are session scoped, they must be moreover
serializable. A class can only be serializable if it has a no argument
constructor.
>
> Question: In a commandLink I can specify #{page2.myInitMethod}
> (Facelets processes the EL and tells JSF where to go) which allows me
> to initialize my backing bean and return String "page2" so that the
> user gets the page.  But I can't do that in step 3) above... the
> backing bean can only return a String that's pre-defined in
> faces-config.xml.  Is there any way to route the browser from a
> backing bean to another page while specifying an initialization
> method?  Assuming I can't return "page2.myInitMethod".
Let JSF do the initialization stuff itself based on bean definitions
made in faces-config.xml. Btw, you can use managed properties if you
want you bean to know about each other. JSF does all this by itself
Example (myRequestBean.getOtherBean() will now return a JSF session
scoped managed bean):
        <managed-bean>
                <managed-bean-name>myRequestBean</managed-bean-name>

<managed-bean-class>com.company.SomeBean</managed-bean-class>
                <managed-bean-scope>request</managed-bean-scope>
                <managed-property>
                     <property-name>otherBean</property-name>

<property-class>com.company.SomeOtherBean</property-class>
                     <value>#{mySessionBean}</value>
                 </managed-property>
        </managed-bean>
        <managed-bean>
                <managed-bean-name>mySessionBean</managed-bean-name>

<managed-bean-class>com.company.SomeOtherBean</managed-bean-class>
                <managed-bean-scope>session</managed-bean-scope>
        </managed-bean>

Moreover, again, you can make page1.java and page2.java a single bean.
Or you can have page1.java have a getter returning page2. In page2.xhtml
EL would then look like #{page1.page2.someProperty}
>
> Motivation: Slowly moving from a plain MyFaces implementation towards
> Seam which requires no-argument empty constructors.  Also looking to
> get Ajax4Jsf running on multi-screen wizard-like flows.  The app
> consists of about 50 backing beans and in the past I used java object
> constructors to initialize the beans, load stuff from the database,
> etc.  I'm sure I'm missing some basic page flow design pattern built
> into JSF and any help is appreciated.
>
I think you are stuck thinking you need a managed bean per form/page. A
JSF Managed bean is simply a bean that has a life duration (depending on
it's scope) and is made available to JSF component using EL expression.
The structure of your bean and their relation does not have to be tied
to your form. A form can combine several beans or a bean can be used by
several forms. Also, only beans you want directly available as EL value
need to be JSF managed. Objects returned by a getter of a JSF managed
bean do not need to be JSF managed.
> Thanks,
>
> Joe