request scope and view scope [duplicate] - jsf

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to choose the right bean scope?
I'm newbie in JSF programming, and I need a clarification about bean scopes. I have already read all the questions about this argument, but is not so clear.
I don't understand the request scope well. I understand that: "This is the default scope and basically the bean is alive throughout a single HTTP request."
So for example, suppose that we ask the browser to open a web page with a form. When we make the request, a request scope bean is created, the life-cycle begins and after the render response phase, the Java bean is destroyed.
Then we fill out the form and we press a button. This will start another HTTP request, right?
In the same context, if a have a view scope bean instead of a request scope bean, what is the difference? How many bean instances are created? Why is it better to use this with a datatable?

The request scope as all your sources including the post linked by BalusC say starts living a short while after your request hits the server, and is destroyed shortly after the last bit of the response has been send back.
Indeed, if you postback a form a new request starts and thus a new request scope. This means everything that is request scoped will be created again. So for a form that is first rendered, and then posted back once, 2 request scoped beans will be created.
The view scope lives as long as you do postbacks to the same view (page). This works by means of the hidden form parameter called javax.faces.ViewState. The value of this is an entry into some kind of logical Map if you use save state on server. How a JSF implementation actually resolves this is not that important here (but yes, it's mostly just a Map).
After the postback JSF is able to retrieve the exact same view scoped beans again by means of this parameter. So for a form that is first rendered, and then posted back once, 1 view scoped bean will be created.
For a datatable you will almost always want to use the view scope. The reason is that you want the data to be the same before and after a postback. If your data is 100% static and/or you don't have postbacks (your table is not in a form), you can use the request scope instead.

Related

Partial triggering from ADF pages is taking long time

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?

Open serval pages without replacing Property in ManagedBean

I have a problem but do not know exactly for what I should look. I do not think I'm the first one has this problem!
It is a Java SE application with JSF & Co, basic frameworks.
The application can be submitted comments to threads. I write a comment and then I open another thread (another Browser-Tab) so the comment is posted in the newly opened thread.
I have a ManagedBean with the attribute "selectedThread". The error results from the fact that the property is replaced by the newer one. How can I fix this problem?
I have several of ideas, but all produce the same problem.
Thank you!
#ManagedBean
#SessionScoped
public class ViewBean {
private Thread selectedThread = new Thread(); //Current opened Threas
private String threadId=""; //ThreadId read out from Database by Id convert to Object
private Comment selectedThreadComment = new Comment(); //Comment to be made
Working/Failure steps:
Open:thread_detail.xhtml?id=10
ThreadId and selected Trip setted
Write a comment (selectedThreadComment setted)
Open:thread_detail.xhtml?id=11
Commit Comment
Comment is understandably persisted for id 11 instead of id 10.
It does not matter which Scope i use. There must be a way to save the Comment according to which site is opened.
I hope now my problem is better-defined!
It sounds like as if the scope of the managed bean is too broad for the data it holds. The symptoms indicate that the managed bean is been placed in the session scope, while the data it holds is specific to a single HTTP request or a single view. A session scoped managed bean instance lives as long as the browser session is established. It is been shared across all requests/views within the same session. Any change initiated by one window/tab would get reflected in another window/tab in the same session.
You should then be placing the bean in the request or the view scope instead if it holds solely request or view scoped data. If you have some data which should surely be kept in the session scope, e.g. the logged-in user, then you should split the current session scoped managed bean out into two managed beans, each in the right scope. The session scoped one is then to be used to hold the data representing the logged-in user and the request/view scoped one is then to be used to hold the data representing the submitted form data and/or the view state. You can use #ManagedProperty to inject the session scoped one into the request/view scoped one.
See also:
How to choose the right bean scope?
How do servlets work? Instantiation, sessions, shared variables and multithreading (to better understand "under the hoods" working of JSF request/session/application scope)

Refreshing a component bind to request-scoped bean

Does anyone have a solution for such a problem:
In my app I'm using a complex, programmatically build dashboard based on the primefaces dashboard. To overcome problems with nonunique id's of the panels building the dashboard, I'm binding this component to a request-scoped bean. I'd also like to rebuild the dashboard based on some changable parameters after clicking a commandButton.
The problem is, that the getter for the dashboard is fired in the Apply Request Values phase, way before the actionListener of the commandButton is fired (in the Invoke Application phase). So, although the dashboard is rebuild eventually, it's not beeing refreshed in the rendered response.
On the other hand, if I try to set immediate attribute of the button to true, the actionListener is fired in the Apply Request Values phase, but still after the getter. Than the lifecycle goes directly to the Render Response phase, and the outcome is the same.
Anyone?
Thank you for the answer. Let me add a bit detail to my problem.
I store a model of a sports tournament as a property of a session scoped bean. It goes like this: the bean has a property "tournament". This class has a list of groups, each with it's table of matches. The idea was to use three different programmatically built components as renderers of this tournament model.
The dashboard would be used for drag-and-drop edition of contestant placement in groups. For viewing match tables and editing their matches I use a tab panel, with panel grid for every table. Finally, I use a panel grid to show a tournament tree. Every of those three components render some part of the model for the user to edit.
Since the model (and therefore those rendering components) are dynamically build depanding on chosable parameters like number of groups for example, i had a problem with id uniqnes when binding them to a session-scoped bean. So I bound them to a request scoped bean. With every request changing the model (mostly ajax) I wanted to rerender those components depending on the parameters set by the user (also stored in the session scoped bean).
The problem is, that when I rebuild the model in the invoke application phase (in a action listener fired by the "rebuild-my-model" button), the components bound to a request-scoped bean have already been "get-ed" from the bean (or so it seems), and they do not refresh on the page.
I would be very gratefull for a clue to what i'm doing wrong, and perhaps a suggestion, if the approach mentioned above is completelly stupid :)
The problem is, that the getter for the dashboard is fired in the Apply Request Values phase, way before the actionListener of the commandButton is fired
I'm not sure why exactly that forms a problem for you. Perhaps you're incorrectly doing business logic in the getter method instead of in the action listener method? Or perhaps you're manually creating the component instead of referencing the JSF-created one and thus always overridding the one in the JSF view?
A proper JSF getter method basically look like this:
public UIComponent getDashboard() {
return dashboard;
}
It should not contain any other line of code. The same applies to the setter method by the way. Any actions wherein you need to manipulate the component's children needs to be done in an action(listener) method, not in a getter/setter method.

Is there a limitation in JSF 2.0 to access attributes of the complex Managed Bean?

The scenario is the following:
A managed bean uses as attributes another managed bean, like customerBean.current.customerAgreement. When I display the data on a pge the expression #{customerBean.current.customerAgreement.agreementTitle} is filled and shows the expected output.
However in an inputText the value is only changed on the screen, not in the value I get back in the managedBean. Is there a limitation on how deep such a structure can be constructed?
No, there is basically no limitation in how deep you can nest beans.
Your problem is caused by something else. Perhaps you are not preserving the same parent beans in the request of the form submit as it was during the request of the form display. Hard to tell without further detail about your code. All what I can suggest is to try making CustomerBean a view scoped bean.

Whats the best way of sending parameters between pages?

We are using JSF in our project (im pretty new to it) were every page have a back bean Java file.
In order to move (redirect) from one page to another, i need to put all the parameters (search criteria) in the request scope before redirecting and then retrieve it back in the next page constructor. When you have few pages deep and you want to come back to the top, it becomes really annoying to maintain.
For example, if i have page 1 with advanced search filters, which redirects to page 2, depending on the chosen item, and from page 2, you get another list were you can go to page 3 for details. Now each time i need to put all the params in the request scope/read them again, store them in hidden fields and get them back.
Whats exactly wrong with this method and whats a better way to do it in JSF?
EDIT: the environment is IBM Rational Application Developer (RAD), which have its own JSF implementation. Not sure if that makes a difference.
Putting request scoped data in session scope will bite you (very) hard if you're going to open the same page in multiple windows/tabs. Only use the session scope if the data itself is also really session scoped (excellent examples are the "logged-in user" and the "shopping cart", you want it to be exactly the same throughout the entire session). Again, don't put request scoped data in the session scope. It hurts both you and the enduser.
Just design your beans smart (it makes no sense to have different beans containing the same data) and make use of h:inputHidden where needed, if necessary in combination with managed property injection. It's indeed a bit a pain to code and maintain. You can on the other hand also just grab Tomahawk <t:saveState> if the to-be-passed data is actually as big as a "whole" managed bean. It costs only a single line in the JSF page and has always been of great assistance.
*For example, if i have page 1 with advanced search filters, which redirects to page 2, depending on the chosen item, and from page 2, you get another list were you can go to page 3 for details. Now each time i need to put all the params in the request scope/read them again, store them in hidden fields and get them back.
Whats exactly wrong with this method and whats a better way to do it in JSF?*
There's nothing wrong with this method. Maybe you coded it the wrong way which caused that it looks unnecessarily overcomplicated. I can't tell much as long as you don't post details about the code used.
As per your edit:
EDIT: the environment is IBM Rational Application Developer (RAD), which have its own JSF implementation. Not sure if that makes a difference.
This is not true. IBM doesn't have any JSF implementation. It has just a component library (the poorly maintained hx prefixed components, also known as "Faces Client Framework"). WSAD/RAD ships with Sun JSF RI (Mojarra) as standard JSF implementation, although it's usually a heavily outdated version. Ensure that you keep it updated.
I'm only starting out with JSF too to be honest, but I thought you can save managed beans in the session scope, thus being able to access the bean on each request? You can also save the state client-side avoiding nastiness about session stickyness and stuff.
So you could save the data you are currently passing as request parameters in a session-scoped managed bean, and it will be available to any requests in that user's session, destroyed when the session times out or is deliberately invalidated (say on user logout).
I don't think JSF currently supports conversation state which I think might be the exact solution to your problem, maybe a session scoped managed bean would be the pragmatic solution?
Make your managed-bean session scoped.
If you are using MyFaces you can use PageFlowScope. If using Seam then use Conversation scope.
If pageflowscope or conversation scope is not available, then use session scoped beans. In addition you can use PhaseListener to initialize or execute specific methods before the page gets called. In you case if the flow is page1 -> page2 -> page3, then initialize the session scoped bean in PhaseListener if page1 gets called.
I'll update with more info if you need.

Resources