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.
Related
I am creating a web application using JSF 2.2.20 in which I am implementing a "kinda wizard" flow which lets the user filling input fields and go back and forth the view pages through navigation. I am using a single bean for all these views.
Let's say I have views A.xhtml, B.xhtml, C.xhtml and D.xhtml, all managed by the same bean MyBean.java
I want my application to be "browser tab scoped", which means that
I do not want my bean's data be re-instantiated after every HTTP Request as it happens with #RequestScoped beans or after view changing as it happens with #ViewScoped, I want the data of my bean to be kept between view changes and redirections so the user can go back and forth between pages without losing the data he has already given.
I do not want to use the #SessionScoped scope since each time the user opens a new tab I want the bean to be re-instantiated starting from page "A.xhtml.
Is there any built-in way to achieve the scenario described above using the current JSF version? In case there is not any, could you please propose any workarounds?
Thanks in advance!
I think #ViewScoped is what you are looking for, but it depends on your exact usage.
Couple of notes:
Use javax.faces.view.ViewScoped. Don't use the deprecated managed bean annotation as it works differently.
#ViewScoped works by storing the beans in the view. So each time you load the page you get a view and a viewId that corresponds to that view. So effectively each load of the page (could be read as 'each browser tab') gets its own bean.
#ViewScoped is a passivating scope. That means your beans, and their injected Dependencies, do need to be Serializable.
Use a recent, up-to-date version of your app server, or if you bring in MyFaces manually, use the latest release. I found a number of older versions implementations buggy 5+ years ago, but it seems to work flawlessly now.
If there is a Page Navigation occurring, you probably want to use FlowScoped. This is a multi-page bean that stays alive until you end the 'flow'.
If neither of these two work, you can always implement your own scope which is surprisingly easy with CDI.
I am working on a ADF application which has a lot of jspx pages. Each jspx page was built with lot of UI components binding to viewscoped managed bean.
Structure of jspx page is like
<jsp:root>
<f:view>
<af:document>
<af:form>
<af:panelgrouplayout>
<af:paneltabbed>
<af:showdetailitem>
<af:table>
And a few UI components(popups,outputtexts,inputtexts etc) inside panelgrouplayout.
My problem is whenever I made a partial page request most of UI components setter methods are getting invoked in managed bean. It seems entire UI View root is reconstructing for every partial request.
For Eg: value change listener on table - Before calling the exact value change event method most of the UI components setter methods are getting triggered (More than once). Restore view and render response phases are taking more time compared to exact business logic.
I already checked from few questions in stackoverflow that binding of components has to be avoided or at least should not bind to any scope more than request/backingbean. For that I have to do lot of refactoring. How can I improve the performance of partial page request?
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
In this beginner's JSF tuorial
section 1.1 says:
JSF UI components and their state are represented on the server with a defined life-cycle of the UI components.
But in the example that follows, I am unable to see how the state of an UI component is managed by the server? The example looks like a standard servlet jsp example minus the servlet mappings.
My other question is that in the example, we are accessing the jsp directly. Is this the standard thing to do in JSF as opposed to using servlet mappings?
First of all, if you're a beginner, I encourage you not to look at that old tutorials and find a good JSF 2.x one. JSF 2 was released in 2009 and you should consider it as the branch to learn, as it brings several advantages comparing with 1.x old versions.
JSF has its own lifecycle for any request you make from the browser which can be a GET or POST request, even an ajax based one. What you basically have to understand about JSF comparing with other frameworks is that it's stateful. In other words, you can keep a component's state from one request to another (you actually have a view state, which can be kept no matter how many requests you do, until you change the view).
Appart from that, about your last statement, in old JSF ages the servlet mapping used to be done over .*jsf suffix. It means, when you make a request for that in the browser, jsf will convert the matching jsp page and display it.
JSF 2 however introduced facelets, which are based in .xhtml view pages. It's now also possible to do the mapping as .xhtml having the source code in an .xhtml too and JSF will make the conversion. The main advantage for this is that end user will not be allowed to see the sources, as browser's request matches source page's url, so JSF servlet will always be invoked.
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?