Why JSF saves the state of UI components on server?
Asked Answered
B

1

114
  1. Until what point in time does JSF save the state of UI components on the server side & when exactly is the UI component's state information removed from the server memory? As a logged-in user on the application navigates though pages, will the state of components keep on accumulating on the server?

  2. I don't understand what is the benefit of keeping UI components state on server !? Isn't directly passing the validated/converted data to managed beans enough? Can I or should I try to avoid it?

  3. Doesn'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, will this big page data be saved as a part of the state of components? This would eat up too much memory. Isn't this a concern ?


Update 1:

Now, it is no longer necessary to save state while using JSF. A high performance Stateless JSF implementation is available for use. See this blog & this question for relevant details & discussion. Also, there is an open issue to include in JSF specs, an option to provide stateless mode for JSF. (P.S. Consider voting for the issues this & this if this is a useful feature for you.)


Update 2 (24-02-2013):

A great news that Mojarra 2.1.19 is out with stateless mode!

See here:

http://weblogs.java.net/blog/mriem/archive/2013/02/08/jsf-going-stateless?force=255

http://java.net/jira/browse/JAVASERVERFACES-2731

http://balusc.blogspot.de/2013/02/stateless-jsf.html

Boger answered 29/3, 2011 at 14:39 Comment(0)
T
208

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. When e.g. the disabled or readonly attribute of an input component is programmatically changed to true and this information is saved in the view state, then this plays an important role as safeguard against tampered requests.


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.numberOfViewsInSession</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. Also when binding is used on a view or session scoped bean, then you're basically unnecessarily holding a deep copy of the whole JSF component tree in the server's memory.

See also:

Tigerish answered 29/3, 2011 at 16:9 Comment(5)
Can you clarify #2? Why can't the component tree just be recreated on each request? What state actually needs to be stored between requests and why? It seems like the only reason to save the component tree between requests would be for performance.Roup
More focused question here: stackoverflow.com/questions/7349174/…Roup
Your answer was very clear to me! The issues about JSF performance and scalability has intrinsic relation to the programmer's implementation! It's need to know use the technology on the right way!Bosom
"Just give the appserver enough memory." Erm, I get the impression that we're talking enterprise level stuff here, if we're talking thousands of concurrent user sessions. If you have enterprise level equipment in an enterprise, you can't just "give the appserver enough memory" like you can in your linux box at home.Quinnquinol
Your answer was very clear and thanks for that. Why does the JSF flash scope was disappear if set javax.faces.PARTIAL_STATE_SAVING to true. getFacesContext().getExternalContext().getFlash().put("buildingId", buildingId).Capuchin

© 2022 - 2024 — McMap. All rights reserved.