Why Jsf Saves the State of UI Components on Server

Why JSF saves the state of UI components on server?

Why does JSF need to save the state of UI components on the server side ?

Because HTTP is stateless and JSF is stateful. The JSF component tree is subject to dynamic (programmatic) changes. JSF simply needs to know the exact state as it was when the form had been displayed to the enduser, so that it can successfully process the whole JSF lifecycle based on the information provided by the original JSF component tree when the form has been submitted back to the server. The component tree provides information about the request parameter names, the necessary converters/validators, the bound managed bean properties and action methods.



Until what point in time does JSF save the state of UI components on the server side and when exactly is the UI component's state information removed from the server memory?

Those two questions seem to boil down to the same. Anyway, this is implementation specific and also dependent on whether the state is saved on server or client. A bit decent implementation will remove it when it has been expired or when the queue is full. Mojarra for example has a default limit of 15 logical views when state saving is set to session. This is configureable with the following context param in web.xml:

<context-param>
<param-name>com.sun.faces.numberOfLogicalViews</param-name>
<param-value>15</param-value>
</context-param>

See also Mojarra FAQ for other Mojarra-specific params and this related answer com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews



As a logged-in user on the application navigates though pages, will the state of components keep on accumulating on the server?

Technically, that depends on the implementation. If you're talking about page-to-page navigation (just GET requests) then Mojarra won't save anything in session. If they are however POST requests (forms with commandlinks/buttons), then Mojarra will save state of each form in session until the max limit. This enables the enduser to open multiple forms in different browser tabs in the same session.

Or, when the state saving is set to client, then JSF won't store anything in session. You can do that by the following context param in web.xml:

<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>

It will then be serialized to an encrypted string in a hidden input field with the name javax.faces.ViewState of the form.



I dont understand what the benefit of keeping the UI component's state on the server side is. Isn't directly passing the validated/converted data to managed beans enough? Can/should I try to avoid it?

That's not enough to ensure the integrity and robustness of JSF. JSF is a dynamic framework with a single entry point of control. Without a state management, one would be able spoof/hack HTTP requests in a certain way (e.g. manipulating disabled, readonly and rendered attributes), to let JSF do different -and potentially hazardful- things. It would even be prone to CSRF attacks and phishing.



And won't that consume too much memory on the server side, if there are thousands of concurrent user sessions? I have an application where users can post blogs on certain topics. This blogs are quite large in size. When there will be post back or request for viewing the blogs, the large blogs will be saved as a part of the state of components. This would consume too much memory. Isn't this a concern?

Memory is particularly cheap. Just give the appserver enough memory. Or if network bandwidth is cheaper to you, just switch state saving to client side. To find the best match, just stresstest and profile your webapp with expected max amount of concurrent users and then give the appserver 125% ~ 150% of maximum measured memory.

Note that JSF 2.0 has improved a lot in state management. It's possible to save partial state (e.g. only the <h:form> will be saved instead of the whole stuff from <html> all the way to the end). Mojarra for example does that. An average form with 10 input fields (each with a label and message) and 2 buttons would take no more than 1KB. With 15 views in session, that should be no more than 15KB per session. With ~1000 concurrent user sessions, that should be no more than 15MB.

Your concern should be more focused on the real objects (managed beans and/or even DB entities) in session or application scope. I've seen lot of codes and projects which unnecessarily duplicates the entire database table into Java's memory in flavor of a session scoped bean where Java is been used instead of SQL to filter/group/arrange the records. With ~1000 records, that would easily go over 10MB per user session.

Why does JSF save component tree state?

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?

Advantage and disadvantage save state in Restore View in client/server JSF 2

First you must read

  • Why does JSF need to save the state of UI components on the server side?
  • What is STATE_SAVING_METHOD parameter in JSF 2.0?

To summarize answer to your question,

Client side:
Saving state on the client results in less of a load on the server at the expense of
additional network traffic. This is because by default, client side is stored as a large hidden
<input> field in web browsers. Saving state on the client also works better in failover
situations because even if the server is down, the state won't be lost.

State saving at client side is having security concerns as well as overhead of serialization of entire JSF tree every time.

Server side:
Prevents CSRF and phishing attacks.

A few questions reagarding UI components state and phases

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?

JSF State Saving initially to server & on session timeout transfer to client?

How is that technically possible? The server can never reliably predict beforehand if the next request would create a new session and thus the response of the current request has to use client side state saving instead of server side state saving. If you ever succeed to implement it using plain JSP/Servlet, feel free to post a JSF specification enhancement request.

Just use client side state saving and make sure that partial state saving is enabled. The overhead is relatively minor as compared to full state saving.

Note that it's possible to use JSF entirely stateless. See also this blog. The only major payoff is that you can't create views dynamically (e.g. by binding, JSTL tags, etc), nor manipulate it after creation (e.g. by adding/removing component's children).

See also:

  • Why JSF saves the state of UI components on server?

What is the architectural purpose of the view state in JSF?

What if the view state did not exist?

The view would then not be mutable from the server side on. For example, you won't be able to attach/remove an UIComponent programmatically.

It's however quite possible to make JSF entirely stateless. See also this blog article.

See also:

  • Why JSF saves the state of UI components on server?

JSF 2.0 partial state saving does not seem to work

Partial state saving does not mean that the state won't be saved in the session. It only means that a part of the component tree state will be saved instead of the entire component tree state. The key idea of partial state saving is that the state of components which wouldn't be changed by the client side in the subsequent request won't be saved. Instead, it is obtained by re-executing the view on the server side during restore view. Only the component state which is sensitive to changes by the client (forms, inputs, buttons, etc) will be saved. The 1K which you see in session is the partial state itself.

To test it yourself, toggle the state on and off by the following context-param in web.xml:

<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>

You'll see that the size increases when the setting is false, which means that the entire component tree is been saved instead.

It is stored in session because that's the only provided by the Servlet API which has a larger scope than the request scope. Storing in request scope would have no value since it wouldn't be available anymore on the subsequent request. The Servlet API has no notion of the view scope like as JSF has (which is under the covers indirectly using the session scope by the way, basically, the view state is the component tree state).

You indeed don't see it anymore when you remove the form since there's actually nothing left which the client could change (i.e. there would be no postback). It would not make sense to save the state then. Besides, there would be nothing to pass the key of the saved state as a hidden input field (with the name javax.faces.ViewState).

See also:

  • What's new in JSF 2.0? - State saving
  • What's the view build time?
  • Why JSF saves the state of UI components on server?

Does JSF cache the state of each component in between the two requests?

The sentence you mention here is about JSF state saving, which saves the state of the component tree. By default, this is done on the server... but you could also do it on the client, to save some mememory. See this: http://wiki.glassfish.java.net/Wiki.jsp?page=JavaServerFacesRI#section-JavaServerFacesRI-WhatAreTheDifferencesBetweenServerAndClientSideStateSavingAndWhatAreTheBenefitsDrawbacksOfEach

Backing beans scope is something else. You can make backing beans session / request / view scoped (or even use another or custom scope). This will have an impact on server memory usage. However, if you do it correctly and don't have big data requirements, you could manage that. For example, you could store as little as possible and reload your data regularly (from db, ...).

All this doesn't mean your data is cached (at least, not the data coming from persistent storage). This is up to you.

So, memory requirements are something to keep in eye. The basic setup for a full-blown Java EE server is typically more than for a php application on an apache server... But, done correctly, making it faster / better / more scalable (cpu / mem) could be simpler to achieve.



Related Topics



Leave a reply



Submit