Request processing JSF lifecycle, only if the component tree was previously saved - jsf

Indeed, very less has been written/shed on the component tree itself, that seems to be source for a whole lot of problems when one takes on understanding JSF.
One of the quote I recently read on a social networking site-
LIBRARY - Because not everything on the Internet is true.
Neither the above nor its opposite holds true either.
This is a screenshot from Anghel Leonard's book- Mastering Java Server Faces 2.2
I think this is plainly wrong. The author seems to be confused on whether its the component tree that gets saved OR the states of the components in the view(tree of UI components)
Considering this thread by BalusC-
When the form is submitted and the view is restored, the JSF
component tree is just rebuilt from scratch and all binding attributes
will just be re-evaluated like described in above paragraph. After the
component tree is recreated, JSF will restore the JSF view state into
the component tree.
Don't forget to read the comments.
Nonetheless, I would love to clarify the above note. Is my understanding perfectly correct?

... only if the component tree was previously saved ...
This is indeed not specific enough. How it really should read is:
... only if the non-transient state of the component tree was previously saved ...

Related

When does mojarra adds a naming container to the list of optional parameters?

In the source of the class AjaxBehaviorRenderer (line 260) there is a line that apparently appends the NamingContainer Id to the list of optional parameters of mojarra.ab(...). I've never come across it so I'm curious as to when it is used:
RenderKitUtils.appendProperty(ajaxCommand, "com.sun.faces.namingContainerId", namingContainerId, true);
line 260
While working on spec issue 790 last week, which should solve a.o. Rendering other form by ajax causes its view state to be lost, how do I add this back?, this was explained to me by Neil Griffin, a portlet guy.
It appears that portlets can have multiple JSF views rendering to the same HTML document, each with its own view state. In portlets, there's a special UIViewRoot instance which implements NamingContainer. During regular rendering, all forms, inputs and commands will have IDs and names prefixed with the view's own client ID. This will work fine during synchronous postbacks. The portlet can this way identify the exact view to restore.
However, during asynchronous postbacks, the jsf.js will create a bunch of additional ajax-specific request parameters such as javax.faces.source, javax.faces.partial.event, etc. Those request parameter names are not prefixed with the view's own client ID. Therefore the portlet cannot associate them with a specific view. Hence the impl issue 3031.
There was another problem of view state identifiers in ajax responses not being properly namespaced this way. Therefore the portlet implementation had to customize the partial response writer in the so-called "JSF bridge". This will be taken into account during implementing spec issue 790. Instead of sniffing a "portlet environment" as in current implementation, there will be checks on UIViewRoot instanceof NamingContainer which is more flexible and portlet-independent. The Mojarra-specific com.sun.faces.namingContainerId will also be removed. Instead, this value will be rendered to <partial-response id="..."> so that the jsf.js can just extract from there.
All in all, not really important if you're only targeting servlet based environments.
As per balusC comment :
It's only interesting for portlet based apps (not servlet based apps).
I can't exactly explain why and what it is used for (a portlet/liferay
guy might), but the portlet specific feature is called "namespaced
parameters". See https://web.liferay.com/web/meera.success/blog/-/blogs/liferay-requires-name-spaced-parameters

Make part of the JSF page stateless

I am working on a JSF application which is supposed to support a big scale of users logged in at the same time. And when we tried with our stress testing, we have observed that a large portion of CPU time is spent on rebuilding and traversing through the component tree.
My first thought was to try to make specific parts of the page stateless and thus be excluded from the component tree. But if I wrap a form element with the f:view being marked as transient:
<f:view transient="true">
<h:form>
....
</h:form>
</f:view>
, all my other forms on the page are also stateless (the hidden input field that is supposed to hold the state has for 'value' attribute value 'stateless': ).
Is there a way to make only specific forms on the page stateless, or the whole page can be either stateless or stateful?
Thanks for any kind of help!
EDIT:
For implementation we are using Mojarra 2.2.7, along with Primefaces 4.0 as a component library and Omnifaces 1.7 for some utility functionalities.
Based on what Balusc has said on this link, applying the transient on a view tag will make the entire view (i.e page) stateless which makes sense because setting transient to true calls the setTransient() on the UIViewRoot object. This can not be accomplished with your current setup. I'm not sure if there is a hack or work around to achieve a single page with multiple states some alternative way.

A few questions reagarding UI components state and phases

Having gone through these excellent posts:
Why JSF saves the state of UI components on server?
Why does JSF save component tree state?
and midway the JavaEE6 tutorial I still have the following questions:
When I am developing a custom UI component whose values (styleClass, value, etc) are either defined statically(in the xhtml) or set via a bean, do I need to explicitly save/restore state in the extended component as well?
Is it correct to say that the scope of the UI components is view scoped?
How is the view identified behaviour? (If I navigate away from a view, the view gets rebuild the next time around. But if I open another tab, it is restored - at least the bean!)
When I am executing an Ajax call, I would expect that 'execute' part of the UI component would be restored&processed and the 'rendered' part would be restored&updated. After running into some problems with UI:repeat, it is not clear to which extend the component tree is to be restored and if is possible to partially edit.
As an example (I am not sure that it works like this): I define a UI:repeat that iterates over some values and creates some Ajax commandlinks. Whenever I call the command, it will restore the whole ui:repeat regardless of the Ajax scope (execute/render) that I have defined. So it will re-render the whole ui:repeat. Furthermore, I don't understand how it could ever -not- restore the ui:repeat as due to being a namingcontainer it will edit the id of my newly added component.
How can I define a build-time component (vs render-time) and why would I want to do this? (It seems that build time components are troublesome when mixed with rendertime, so why have both)
Thanks
When I am developing a custom UI component whose values (styleClass, value, etc) are either defined statically(in the xhtml) or set via a bean, do I need to explicitly save/restore state in the extended component as well?
Yes. You normally use StateHelper for this.
See also:
How to save state when extending UIComponentBase
JSF custom component: support for arguments of custom types, the attribute setter is never invoked
Adding Custom Attributes to Primefaces Autocomplete Component in JSF
Is it correct to say that the scope of the UI components is view scoped?
Absolutely not. UI component instances are request scoped. Only anything which is stored via StateHelper is in essence view scoped (and restored into newly created component instances during "restore view" phase).
See also:
JSF composite component - weird behavior when trying to save state
Backing bean in composite component is recreated on every request
How is the view identified behaviour? (If I navigate away from a view, the view gets rebuild the next time around. But if I open another tab, it is restored - at least the bean!)
It's likely requested from browser cache. Try submitting a form therein. The chance is big that you get a ViewExpiredException. You need to tell the browser to not cache dynamic pages. Putting a breakpoint on bean's constructor would also confirm that it's never been invoked.
See also:
Avoid back button on JSF web application
Is JSF 2.0 View Scope back-button safe?
javax.faces.application.ViewExpiredException: View could not be restored
When I am executing an Ajax call, I would expect that 'execute' part of the UI component would be restored&processed and the 'rendered' part would be restored&updated.
This is not true as to restore part. The "whole" view state is restored. Note that the view state does since JSF 2.0 not necessarily represent the entire component tree. You've found the explanation/answer to that already in the two links mentioned in your question.
How can I define a build-time component (vs render-time) and why would I want to do this? (It seems that build time components are troublesome when mixed with rendertime, so why have both)
This is called a "tag handler". I.e. just extend from TagHandler instead of UIComponent and implement according its contract. Tag handlers are useful if the sole goal is to build the view (the JSF component tree). They do not appear in the JSF component tree. As to when to create a custom component or a custom tag handler, check the "components" and "taghandlers" sections of OmniFaces showcase, it may give some new insights as to real world use cases of those things.
See also:
Custom Facelet component in JSF
JSTL in JSF2 Facelets... makes sense?

Why does JSF save component tree state?

There appears to be a difference between managed bean state and component tree state. You can control managed bean state by using annotations like #RequestScoped and #SessionScoped, but it seems you don't have a choice in whether the component tree state is saved or not (although you can choose whether it is saved on the server or client).
It seems like component tree state should only be needed for the duration of a single request as a temporary data structure to help process a request. It should be rebuilt from scratch for each request. With JSF 2.0 partial state saving makes the situation better because only form data is saved, but I don't understand why having even form data from the previous request is useful.
If your application uses only request scope managed beans then it especially doesn't make sense to save component tree state between requests. Even if your application has session scope managed beans I would assume that the managed beans would hold the state and the component tree still wouldn't need to have any state between requests.
Adding to the previous answer, ever since JSF 2.0 something called partial state saving is used by default.
The default view description language in JSF (Facelets) creates the whole component tree from the original Facelet after every request and initializes the components from their corresponding tag attributes. It then marks the state.
Every subsequent state change is then remembered as a delta change, and it's this state that is actually being saved. It might just well turn out that there simply are no such changes, and then the view state is empty (because of a bug, the state was never truly empty, but that has been recently fixed. See http://java.net/jira/browse/JAVASERVERFACES-2203 for details)
So the big question is, what's actually in this state then when it's non-empty?
As BalusC already remarked, this could hold dynamic changes to the component tree. Those changes can either be initiated from backing beans, or from within static components. A simple example of the kind of component that does this dynamic changing is a table component that creates child column components based on the actual number of columns in a data set.
Another important usage for the view state is remembering values that have been changed inside components, but have not been pushed into the model. This can be such things as flicking a switch in a switch component, moving a slider in a dial component etc.
One particular example is the viewParam component, which remembers the request parameter (query string parameter for GET or non-faces POST parameter) with which it was initialized. See this for some more info about that: http://arjan-tijms.omnifaces.org/2011/07/stateless-vs-stateful-jsf-view.html
There is also a strong relation with stateful components remembering UI state and conversion or validation that fails. In this case, the UI components will remember the values entered by the user, and will remember that there was a conversion/validation error.
Yet another usage for the state is optimization. Some components calculate values that they deem to be expensive to calculate and store these in the view state. For instance, UIInput components do this after the first post-back:
private boolean validateEmptyFields(FacesContext ctx) {
if (validateEmptyFields == null) {
ExternalContext extCtx = ctx.getExternalContext();
String val = extCtx.getInitParameter(VALIDATE_EMPTY_FIELDS_PARAM_NAME);
if (val == null) {
val = (String) extCtx.getApplicationMap().get(VALIDATE_EMPTY_FIELDS_PARAM_NAME);
}
if (val == null || "auto".equals(val)) {
validateEmptyFields = isBeansValidationAvailable(ctx);
} else {
validateEmptyFields = Boolean.valueOf(val);
}
}
return validateEmptyFields;
}
After this validateEmptyFields is stored in the view state so it doesn't have to be calculated again upon the following form submits. An improvement would be if users can choose between re-calculating or storing (the well know time-space optimization).
The very concept of state is what has plagued web application development since its early conception. Everyone wants to have interactions that are essentially stateful, yet almost nobody wants to handle it or even think about it.
JSF has been trying to provide an answer here, but it's obviously not perfect and there's room for improvement. JSF's insistence on being able to restore view state (even empty view state) can be troublesome, although as was mentioned in another answer it does provide an implicit protection against CSRF. JSF 2.2 will get more explicit CSRF protection (see e.g. http://arjan-tijms.omnifaces.org/p/jsf-22.html#869), so maybe we will see some change here in the future.
Having an option to turn off state per component and having an easy hook to restore state incase the framework can't (as in ASP.NET) might also be helpful.
Because the component tree can be altered programmatically depending on the initial request. This is not necessarily reproduceable on the subsequent request whenever the form data has to be processed.
Further I have the impression that you think that the component tree also holds the model values. This is not true. It only holds references (by expression language) to the model values (the managed bean properties). The view state does not copy/duplicate/contain the model state. It's just a pure UI component tree. Perhaps your confusion is based on this. Note that the term "form data" is to be interpreted as submitted values and model values.
See also:
Why JSF saves the state of UI components on server?

Difference between JSF view instances: new view, initial view, and postback view

I did some research on JSF view instances: new view, initial view, and postback view. But, I am still not quite sure about the differences. It's kind of confusing and I haven't been able to find a good explanation on that. Can somebody put some light on this one?
That was how JSF 1.0/1.1 works. They are explained in detail in this ancient IBM article. But you should forget and ignore the whole article (see also "Editor's notes" section on top which was edited in afterwards). It does not apply anymore since JSF 1.2 and newer (including JSF 2.x). There is only "initial view" and "postback view". The "new view" does not exist anymore.
An initial view is been created upon a GET request and an existing view is been reused upon a POST request. When a GET request results in a response with a <h:form> for POST, then the (partial) view is referenced by a hidden input field with name javax.faces.ViewState. This very same same view will be restored and used to process the form submit (the postback).

Resources