Hi Andrew :-),
The question wasn't well asked, I'm sorry. I will try my best:
Today if JSF receives a request from a form that has in its component list
the element ( <tc:in value="#{cat.color}"> ) and that none of the scopes has
the attribute "cat" stored in it, the request parameter will rest as is: no
action will be exerced in the UPDATE_MODEL_VALUES phase.
And this will happen even if we have declared a backing bean with the name
"cat" (in any of the scopes). The backing bean "cat" will be created at the
RENDER_RESPONSE phase because it's there! that it will realize through its
VariableResolverImpl that it needs a backing bean with that name and that
it's still not instantiated.
Now if the backing bean "cat" is session scoped, the first RENDER_RESPONSE
will instantiate the bean, so it's not possible to have an incoming form
request without having an already instantiated backing bean (as long as the
request is coming from the same application).
The problem is when the backing bean "cat" is request scoped: the first
RENDER_RESPONSE will instantiate the bean and add it to the request
attributes, but when the request life cycle is finished (the page is
displayed), the attribute will die with its request. So when we submit the
form, we are again in a blank situation (no bean in any scope), until we
arrive to the RENDER_RESPONSE phase. Again there it's too late, the
INVOKE_APPLICATION phase has passed and no added value was done by the JSF
framework.
The idea is to detect the need for a backing bean before the
INVOKE_APPLICATION phase, and to have the bean populated at that phase. So
insted of waiting until we reach the RENDER_RESPONSE phase, we can do our
checks and instantiations in the UPDATE_MODEL_VALUES.
Now let's discuss the bugs that may result from this design change:
- The developer may want to control the creation time of the backing
bean, in that case, he doesn't need a backing bean but a standard request
attribute.
- The developer may have its own attributes in the request and see
them overriden by JSF (because request parameters happen to be interpreted
by JSF as a request for backing bean instantiation): we can log a warning in
this case and do not instantiate the backing bean. But I saw in your
that you agree it's not a good idea to have attribute naming conflicts, so
the warning can only be a compilation runtime extention.
I hope you understood what I mean, I'm sorry for writing so long mails and
taking your time, but the idea seams important to me...
Regards,
Zied Hamdi
2007/6/21, Andrew Robinson <[EMAIL PROTECTED]>:
It sounds like you are simply asking about the name resolution from
the EL engine. If that is the case, then there may be different
options for you, but I am not sure if I still understand your use case
all the way.
If it is about name resolution, then the best place I can send you is
to the MyFaces source code. If you open
org.apache.myfaces.el.VariableResolverImpl
You will see the source that is responsible for resolving JSF variable
names in the MyFaces implementation.
When someone asks for "#{cat}", it will check in order:
1) built-in (facesContext for example)
2) request
3) session
4) application
5) managed bean
Therefore if you have "cat" mapped in the servlet application scope
and a bean named "cat", you will only get one from the servlet
application scope and never the managed bean. If you have two managed
beans with the same name, one is booted and never will be returned
(hence the warnings).
Think of the managed beans as being registered in a Map. Only one
value is possible.
If you are having name conflicts, I would suggest using EL naming
patterns. This could be XML namespace style, java package style, or
your own custom style.
So instead of "cat", you could use "requestscope-cat" or
"request-com-mycomp-cat" or whatever.
Now if you still want more functionality, then may I suggest looking
into writing your own VariableResolver by extending the one from
MyFaces or look into writing your own property resolvers (see
faces-config information or other JSF specification information for
information on these).
Hope that helps some,
Andrew
On 6/20/07, Zied Hamdi <[EMAIL PROTECTED]> wrote:
> Hi Andrew,
>
> Let's imagine we have declared a backing bean as request scoped (say
cat).
> On submit of a form that contains information related to that bean, even
> though we have specified in the form value attributes that we point to a
> bean with the given name (eg: value="#cat.color"), there isn't any
attempt
> to verify if a backing bean with that name was declared (naturally if it
> isn't already in any scope).
>
> I'm new to JSF and I tried an example like this, thinking the framework
will
> recognise I'm trying to fill request parameters prefixed with "cat" into
my
> declared request scope bean with the same name, but when I aquired
control
> "at the application scope" I didn't find any bean under the key "cat" in
my
> request.
>
> explanations : I'm not very good in english, maybe I was misunderstood:
>
> There is nothing in the HttpServletRequest JavaDoc that says you
> cannot set request attributes at any time once the request has been
> created:
>
>
> I said that before the MVC frameworks, when we had only servlets and
jsps,
> it wasn't possible to intercept the request and add it attributes, all
we
> had was what comes from the HTTP protocol: parameters. Now that we now
what
> data model is expected on the other side, we can understand that when a
> parameter has a given naming pattern, it is designed to fill the
> corresponding model data.
> Instantiating beans before
> they have been referenced would create performance and logic bugs in
> JSF applications.
>
>
> Instantiating all the declared request beans will lead to even worser
> results than the actual, because for every request lifecycle we will
have
> all the possible beans in memory, plus the overcomputation of the
> instantiation. What I meant was: by the name "pattern" of UIComponent's
> value attribute, we can understand that a UIComp is supposed to fill the
> field of a - page, request, session or application scoped - bean with
the
> name "cat" (again :-)). If we happen to have in our faces-config a bean
with
> the name "cat", and that theresn't any bean instanciated in the server
> memory (in any scope) with this same name, so we are the most probably
> trying to instanciate the declared bean and profit from all JSF phases
to
> have a validated and ready to use bean. If it happens that the value
> attribute didn't mean that bean (I mean not the one declared in the
> faces-config) than the user would rather rename his bean because sooner
or
> later, he will get bad surprises. (All the constraints it adds is a sort
of
> type checking, and no one will say that adding type checking is bad for
safe
> programming)
>
> I agree there are conditions to instantiate the bean without adding bugs
> (like putting a bean in the request, so hiding the original one that was
in
> (or will be added to) the session), but cases like this are very
probably
> developper errors because using the same name in two scopes is definitly
a
> bad practice. Cases like this could be discouraged by warning logs.
> Otherwise, I don't see where there can be logic bugs, but the question
needs
> certainly more reflection.
>
>
>
> 2007/6/20, Andrew Robinson <[EMAIL PROTECTED]>:
> > Beans are created on an as needed basis. Instantiating beans before
> > they have been referenced would create performance and logic bugs in
> > JSF applications.
> >
> > If you want to force the instantiation of beans at a given time,
> > simply ask them to be created in a phase listener.
> >
> > The following code will force that an instance is created:
> >
> >
> application.createValueBinding("#{beanName}").getValue(facesContext);
> >
> > BTW, why can't you set a request attribute in a phase listener in the
> > before restore view phase?
> >
> > There is nothing in the HttpServletRequest JavaDoc that says you
> > cannot set request attributes at any time once the request has been
> > created:
> >
> > http://tinyurl.com/29ypjz
> >
> > Even though I proposed a means to force the creating of request beans,
> > I don't see a valid use case for this. What are you trying to do that
> > would need to force a request bean to be created before a view is
> > restored? If you can answer that perhaps we can help find another way
> > of doing what you want with better design and performance metrics.
> >
> > -Andrew
> >
> > On 6/20/07, Zied Hamdi <[EMAIL PROTECTED]> wrote:
> > > Hi MyFaces people,
> > >
> > > I'd like to ask a question that leeded me to an interesting
concusion:
> > >
> > > Why now that we are in a "managed" environement can't we still use
the
> > > request attributes for incoming requests (to the server)?
> > >
> > > It's not complicted to have backward compatibility with the servlet
> > > specification, request attributes can't exist when we enter the
> > > Servlet.service() method. So now that we know that, we know that we
> can't
> > > override an existing attribute if we create one in the restore view
> phase of
> > > JSF. So why don't we create request scoped backing beans in this
phase
> so
> > > that we avoid unnecessary session obesity.
> > >
> > > The idea is that with the current design of JSF, we must have for
every
> data
> > > object (let's say data objects instead of DTO for objects that go to
the
> > > front end) an instance living in the session scope, and everybody
knows
> that
> > > we don't matter if they are not reset to null when we don't need
them.
> The
> > > use case is that we usually need one of them at a time. But putting
them
> in
> > > the request scope isn't sufficient because they are not transferred
to
> the
> > > next request where we need to get the user entred values. If they
were
> > > created in the restore view phase, they would live longer and we
could
> > > profit of their existence for all the cycle instead of having them
at
> the
> > > moment the page is being displayed.
> > >
> > > I thing the way it's done today is historical: nothing was managed
> before
> > > JSF and Struts, and we pay today for that historical technical
> constraint
> > > (that it isn't possible to pass attributes in the HTTP protocol). To
> compare
> > > the problem: with Struts, the memory can be released from the server
as
> soon
> > > as the action has finished its execution...
> > >
> > > --
> > > Zied Hamdi
> > > zatreex.sourceforge.net
> >
>
>
>
> --
>
> Zied Hamdi
> zatreex.sourceforge.net
--
Zied Hamdi
zatreex.sourceforge.net