You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Francisco Passos <fr...@gmail.com> on 2007/05/07 19:49:50 UTC

Initializing Beans - Two problems

Hello there.

Please bear with me in this description.

I'm trying to get my request-scoped beans to be initialized (fetch stuff
from database, etc.) whenever they do not originate from a postback (and
keeping the state during postbacks using t:saveState). I've implemented a
PhaseListener which checks for the proper conditions I want to initialize my
beans in and invokes a method from the bean interface my beans implement.

This is my implementation of said PhaseListener:

public void beforePhase(PhaseEvent event) {

    if (event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES) ||
event.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {

        GenericBean bean = (GenericBean) FacesContext.getCurrentInstance
().getApplication().getVariableResolver().resolveVariable(
FacesContext.getCurrentInstance(), "pesquisaFichaBean");
        if (bean != null && !bean.isPostback()) {
            logger.info("Initializing bean: " + bean);
            bean.initialize();
        }
    }
}


However I have two problems with this approach.

The first problem has to do with having to use the bean names explicitly
("pesquisaFichaBean" in this example). Is there any way I can know the names
of the registered beans? Or is there another alternative I'm not seeing?


The second problem is as follows. By now I have a couple of beans that I use
in my application. So, for this to work, I have to repeat what I've shown
above for the various beans. The problem is that the resolveVariable method
never returns null - even if I have not yet instantiated any bean with that
particular name. It seems to me that, since no bean yet exists, it is
instantiated (as it would be if it were referenced in a xhtml page).

Which means that everytime I enter a new page (no postback), all my
instantiated beans are initialized and the remaining are instantiated on the
spot and initialized as well!!! This obviously brings me back to the problem
of accessing the database for nothing.

I hope I explained the situation well, here's an example: suppose some pages
require "beanA", others "beanB". When I enter a page which references
"beanA" but does not reference "beanB", both will be initialized! The
difference is beanA will be used and beanB will.

What solutions are there for this? Is there any way I can look into the
variables without triggering their instantiation?

Re: Best way to set http headers

Posted by Simon Kitching <si...@rhe.co.nz>.
Dfr wrote:
> 
> Hello,
> 
> Is there a best way to set http headers with JSF ?
> Currently i need set different Last-Modified values for different JSF 
> pages. It generally based on data fetched from storage by backing beans.
> Is it ok to set such headers in getter methods of bean ? I currently 
> don't like this approach being fan of SRP(Single Responsibility 
> Principle), i.e. getter must return data, but not set headers.
> 
> And  one more question, does anoyone set "Cache" headers manually or 
> just stick with defauts ?
> 
> Thank you.
> 
> 

I do set cache headers in the app I currently work on, but do it from a 
standard servlet filter rather than at the JSF level.

If the headers you want to set can be deduced from just the view id then 
I suggest you write your code as a PhaseListener that runs on "before 
render".

If you need page-specific data then I suggest you write a custom JSF 
component that you add to the top of every page that needs the headers 
set. This header can then evaluate an EL expression to fetch whatever it 
needs to determine the correct Last-Modified value. This seems more 
elegant than having backing beans explicitly writing headers. However it 
is a lot more work. As an easier alternative, something like this:
  <h:outputText style="display:none" value="#{bean.doSomething}"/>
can be used to invoke arbitrary back-end logic during rendering. It's 
hacky but there is no component I know of that can invoke a backing bean 
method without generating output to the page. The display:none style 
makes it pretty clear that this is really just triggering a method call.

Regards,

Simon

Best way to set http headers

Posted by Dfr <df...@wm.ru>.
Hello,

Is there a best way to set http headers with JSF ?
Currently i need set different Last-Modified values for different JSF 
pages. It generally based on data fetched from storage by backing beans.
Is it ok to set such headers in getter methods of bean ? I currently 
don't like this approach being fan of SRP(Single Responsibility 
Principle), i.e. getter must return data, but not set headers.

And  one more question, does anoyone set "Cache" headers manually or 
just stick with defauts ?

Thank you.



Re: Initializing Beans - Two problems

Posted by Francisco Passos <fr...@gmail.com>.
Hello there.

The first option presented is the simplest, it's working and I'm keeping it
for now, although I don't particularly like it for its elegance.

Thank you.

On 5/8/07, Beelen, Marco <ma...@merck.com> wrote:
>
>  Hello Francisco,
>
> There are some possible alternatives:
>
> 1) A JSF implementation should call the setters for the managed-properties
> of your bean in the order in which they are specified in the
> jsf-config.xml.
> Your could add an addional property 'startInitialization' as the last
> managed-property and perform the initialization in the setter for that
> property.
>
> 2) Make your classes implement the interface InitializingBean and use
> JSF-Spring (  http://jsf-spring.sourceforge.net/ ) to make sure that the
> initializing method will be called.. ( There have been reports about
> classloader issues with JSF-spring, but I didn't ran into them yet and am
> using this to my satisfaction. )
>
> 3) When you are using Spring 2.0.x, you can move the definition of your
> managed-bean entirely to a spring applicationContext.xml and use
> org.springframework.beans.factory.InitializingBean without JSF-spring,
> although I don't fancy this approach I heard of some whom favour this.
>
> 4) Start using a JSF1.2 implementation and using the @PostConstruct
> annotation to mark the method to be called after the bean has been created
> and it's managed-properties are set.
>
>
>
> With kind regards,
>   Marco Beelen
>
>
>
>
>
>  ------------------------------
> *From:* Simon Lessard [mailto:simon.lessard.3@gmail.com]
> *Sent:* maandag 7 mei 2007 20:07
> *To:* MyFaces Discussion
> *Subject:* Re: Initializing Beans - Two problems
>
> Hello Francisco,
>
> You could implement your own VariableResolver using decorator pattern
> delegating to the original resolver then initializing the bean if your
> condition is true. The code would look as follow:
>
> public Object resolveVariable(FacesContext context, String name) {
>   Object o = delegate.resolveVariable(context, name);
>   if (o != null && (o instanceof GenericBean)) {
>     GenericBean bean = (GenericBean)o;
>     if (!bean.isPostback()) {
>       logger.info("Initializing bean: " + bean);
>       bean.initialize();
>     }
>   }
> }
>
> Regards,
>
> ~ Simon
>
> On 5/7/07, Francisco Passos <fr...@gmail.com> wrote:
> >
> > Hello there.
> >
> > Please bear with me in this description.
> >
> > I'm trying to get my request-scoped beans to be initialized (fetch stuff
> > from database, etc.) whenever they do not originate from a postback (and
> > keeping the state during postbacks using t:saveState). I've implemented a
> > PhaseListener which checks for the proper conditions I want to initialize my
> > beans in and invokes a method from the bean interface my beans implement.
> >
> > This is my implementation of said PhaseListener:
> >
> > public void beforePhase(PhaseEvent event) {
> >
> >     if (event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES) ||
> > event.getPhaseId().equals(PhaseId.RENDER_RESPONSE )) {
> >
> >         GenericBean bean = (GenericBean) FacesContext.getCurrentInstance
> > ().getApplication().getVariableResolver().resolveVariable(
> > FacesContext.getCurrentInstance(), "pesquisaFichaBean");
> >         if (bean != null && !bean.isPostback()) {
> >             logger.info("Initializing bean: " + bean);
> >             bean.initialize();
> >         }
> >     }
> > }
> >
> >
> > However I have two problems with this approach.
> >
> > The first problem has to do with having to use the bean names explicitly
> > ("pesquisaFichaBean" in this example). Is there any way I can know the names
> > of the registered beans? Or is there another alternative I'm not seeing?
> >
> >
> > The second problem is as follows. By now I have a couple of beans that I
> > use in my application. So, for this to work, I have to repeat what I've
> > shown above for the various beans. The problem is that the resolveVariable
> > method never returns null - even if I have not yet instantiated any bean
> > with that particular name. It seems to me that, since no bean yet exists, it
> > is instantiated (as it would be if it were referenced in a xhtml page).
> >
> > Which means that everytime I enter a new page (no postback), all my
> > instantiated beans are initialized and the remaining are instantiated on the
> > spot and initialized as well!!! This obviously brings me back to the problem
> > of accessing the database for nothing.
> >
> > I hope I explained the situation well, here's an example: suppose some
> > pages require "beanA", others "beanB". When I enter a page which references
> > "beanA" but does not reference "beanB", both will be initialized! The
> > difference is beanA will be used and beanB will.
> >
> > What solutions are there for this? Is there any way I can look into the
> > variables without triggering their instantiation?
> >
>
>
> ------------------------------------------------------------------------------
> Notice: This e-mail message, together with any attachments, contains
> information of Merck & Co., Inc. (One Merck Drive, Whitehouse Station,
> New Jersey, USA 08889), and/or its affiliates (which may be known
> outside the United States as Merck Frosst, Merck Sharp & Dohme or MSD
> and in Japan, as Banyu - direct contact information for affiliates is
> available at http://www.merck.com/contact/contacts.html) that may be
> confidential, proprietary copyrighted and/or legally privileged. It is
> intended solely for the use of the individual or entity named on this
> message. If you are not the intended recipient, and have received this
> message in error, please notify us immediately by reply e-mail and then
> delete it from your system.
>
>
> ------------------------------------------------------------------------------
>

RE: Initializing Beans - Two problems

Posted by "Beelen, Marco" <ma...@merck.com>.
Hello Francisco,
 
There are some possible alternatives:
 
1) A JSF implementation should call the setters for the
managed-properties of your bean in the order in which they are specified
in the jsf-config.xml.
Your could add an addional property 'startInitialization' as the last
managed-property and perform the initialization in the setter for that
property.
 
2) Make your classes implement the interface InitializingBean and use
JSF-Spring (  http://jsf-spring.sourceforge.net/
<http://jsf-spring.sourceforge.net/>  ) to make sure that the
initializing method will be called.. ( There have been reports about
classloader issues with JSF-spring, but I didn't ran into them yet and
am using this to my satisfaction. )
 
3) When you are using Spring 2.0.x, you can move the definition of your
managed-bean entirely to a spring applicationContext.xml and use
org.springframework.beans.factory.InitializingBean without JSF-spring,
although I don't fancy this approach I heard of some whom favour this.
 
4) Start using a JSF1.2 implementation and using the @PostConstruct
annotation to mark the method to be called after the bean has been
created and it's managed-properties are set.
 
 
 
With kind regards,
  Marco Beelen
 
 
 
 
 

________________________________

From: Simon Lessard [mailto:simon.lessard.3@gmail.com] 
Sent: maandag 7 mei 2007 20:07
To: MyFaces Discussion
Subject: Re: Initializing Beans - Two problems


Hello Francisco,

You could implement your own VariableResolver using decorator pattern
delegating to the original resolver then initializing the bean if your
condition is true. The code would look as follow:

public Object resolveVariable(FacesContext context, String name) {
  Object o = delegate.resolveVariable(context, name);
  if (o != null && (o instanceof GenericBean)) {
    GenericBean bean = (GenericBean)o; 
    if (!bean.isPostback()) {
      logger.info("Initializing bean: " + bean);
      bean.initialize();
    }
  }
}

Regards,

~ Simon


On 5/7/07, Francisco Passos <fr...@gmail.com> wrote: 

	Hello there.
	
	Please bear with me in this description.
	
	I'm trying to get my request-scoped beans to be initialized
(fetch stuff from database, etc.) whenever they do not originate from a
postback (and keeping the state during postbacks using t:saveState).
I've implemented a PhaseListener which checks for the proper conditions
I want to initialize my beans in and invokes a method from the bean
interface my beans implement. 
	
	This is my implementation of said PhaseListener:
	
	public void beforePhase(PhaseEvent event) {
	
	    if (event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES)
|| event.getPhaseId().equals(PhaseId.RENDER_RESPONSE )) {
	    
	        GenericBean bean = (GenericBean)
FacesContext.getCurrentInstance().getApplication().getVariableResolver()
.resolveVariable(FacesContext.getCurrentInstance(),
"pesquisaFichaBean");
	        if (bean != null && !bean.isPostback()) { 
	            logger.info("Initializing bean: " + bean);
	            bean.initialize();
	        }
	    }
	}
	
	
	However I have two problems with this approach.
	
	The first problem has to do with having to use the bean names
explicitly ("pesquisaFichaBean" in this example). Is there any way I can
know the names of the registered beans? Or is there another alternative
I'm not seeing? 
	
	
	The second problem is as follows. By now I have a couple of
beans that I use in my application. So, for this to work, I have to
repeat what I've shown above for the various beans. The problem is that
the resolveVariable method never returns null - even if I have not yet
instantiated any bean with that particular name. It seems to me that,
since no bean yet exists, it is instantiated (as it would be if it were
referenced in a xhtml page). 
	
	Which means that everytime I enter a new page (no postback), all
my instantiated beans are initialized and the remaining are instantiated
on the spot and initialized as well!!! This obviously brings me back to
the problem of accessing the database for nothing. 
	
	I hope I explained the situation well, here's an example:
suppose some pages require "beanA", others "beanB". When I enter a page
which references "beanA" but does not reference "beanB", both will be
initialized! The difference is beanA will be used and beanB will. 
	
	What solutions are there for this? Is there any way I can look
into the variables without triggering their instantiation?
	



------------------------------------------------------------------------------
Notice:  This e-mail message, together with any attachments, contains
information of Merck & Co., Inc. (One Merck Drive, Whitehouse Station,
New Jersey, USA 08889), and/or its affiliates (which may be known
outside the United States as Merck Frosst, Merck Sharp & Dohme or MSD
and in Japan, as Banyu - direct contact information for affiliates is 
available at http://www.merck.com/contact/contacts.html) that may be 
confidential, proprietary copyrighted and/or legally privileged. It is 
intended solely for the use of the individual or entity named on this 
message. If you are not the intended recipient, and have received this 
message in error, please notify us immediately by reply e-mail and then 
delete it from your system.

------------------------------------------------------------------------------

Re: Initializing Beans - Two problems

Posted by Simon Lessard <si...@gmail.com>.
Hello Francisco,

You could implement your own VariableResolver using decorator pattern
delegating to the original resolver then initializing the bean if your
condition is true. The code would look as follow:

public Object resolveVariable(FacesContext context, String name) {
  Object o = delegate.resolveVariable(context, name);
  if (o != null && (o instanceof GenericBean)) {
    GenericBean bean = (GenericBean)o;
    if (!bean.isPostback()) {
      logger.info("Initializing bean: " + bean);
      bean.initialize();
    }
  }
}

Regards,

~ Simon

On 5/7/07, Francisco Passos <fr...@gmail.com> wrote:
>
> Hello there.
>
> Please bear with me in this description.
>
> I'm trying to get my request-scoped beans to be initialized (fetch stuff
> from database, etc.) whenever they do not originate from a postback (and
> keeping the state during postbacks using t:saveState). I've implemented a
> PhaseListener which checks for the proper conditions I want to initialize my
> beans in and invokes a method from the bean interface my beans implement.
>
> This is my implementation of said PhaseListener:
>
> public void beforePhase(PhaseEvent event) {
>
>     if (event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES) ||
> event.getPhaseId().equals(PhaseId.RENDER_RESPONSE )) {
>
>         GenericBean bean = (GenericBean) FacesContext.getCurrentInstance
> ().getApplication().getVariableResolver().resolveVariable(
> FacesContext.getCurrentInstance(), "pesquisaFichaBean");
>         if (bean != null && !bean.isPostback()) {
>             logger.info("Initializing bean: " + bean);
>             bean.initialize();
>         }
>     }
> }
>
>
> However I have two problems with this approach.
>
> The first problem has to do with having to use the bean names explicitly
> ("pesquisaFichaBean" in this example). Is there any way I can know the names
> of the registered beans? Or is there another alternative I'm not seeing?
>
>
> The second problem is as follows. By now I have a couple of beans that I
> use in my application. So, for this to work, I have to repeat what I've
> shown above for the various beans. The problem is that the resolveVariable
> method never returns null - even if I have not yet instantiated any bean
> with that particular name. It seems to me that, since no bean yet exists, it
> is instantiated (as it would be if it were referenced in a xhtml page).
>
> Which means that everytime I enter a new page (no postback), all my
> instantiated beans are initialized and the remaining are instantiated on the
> spot and initialized as well!!! This obviously brings me back to the problem
> of accessing the database for nothing.
>
> I hope I explained the situation well, here's an example: suppose some
> pages require "beanA", others "beanB". When I enter a page which references
> "beanA" but does not reference "beanB", both will be initialized! The
> difference is beanA will be used and beanB will.
>
> What solutions are there for this? Is there any way I can look into the
> variables without triggering their instantiation?
>