I have a JSF application where the backing bean for one of my xhtml pages is ViewScoped. I have several variables including a Map object. It was my understanding that the bean would live as long as I return null as the outcome on an action. However, the Map object in the bean is set back to null when the page is finished initially loading. I have a command button to perform some logic using the Map object, but it is null at the point where I click the command button.
Is there any way to retain the Map object values? If I use session scope on the bean, the behavior of the application is not what I want. I want to be able to make multiple calls to the xhtml page with different request parameters.
To my understanding in JSF ViewScoped beans, the constructor is triggered when the page loads. So this means a new instance of your map is created every time an user accesses it.
Did you populate the map during the bean's initialization using the init() method or in the bean's constructor?
K. Tsang CEng MBCS PMP PMI-ACP OCPJEA OCPJP
posted 6 years ago
I did not populate the map either in the init or the constructor. My xhtml page has a gridPanel which is bound to a variable in the bean. So the getMainGird method is invoked which draws the page. This method is where the map is populated.
I see. Look to me that your map variable may be out of scope by the time the getMainGrid() method is done causing the button click later on using a null map object.
If your map is a local variable (inside getMainGrid) then make it into an instance variable. If your variable is already an instance variable try printing out the map entries at the end to confirm the map is indeed populated and first thing in the button click method to confirm its existence.
I don't think you're applying JSF's Inversion of Control (IoC) effectively. You say " I want to be able to make multiple calls to the xhtml page with different request parameters."
There's a reason why I get so pedantic here. Using improper terminology causes people to make false assumptions which causes issues in design and implementation. So:
1. You don't "call an xhtml page". You Navigate to a View. The View Template is the xhtml. You don't "call" it, since it's really data, not code. The code is (or SHOULD be) in the backing beans.
2. You don't "pass request parameters". Yes, JSF2 does support doing it that way, but JSF1 didn't. And for the simple reason that parameters are not the preferred way to transfer data into a JSF backing bean.
When using IoC, you would typically set the "parameters" up in a preceding View's action. A common way to do this is by injecting one or more beans (parameter beans) of Session scope or higher into the source view's backing bean so that its action method can manipulate the parameter bean's properties, and let the action navigate to the destination view, whose backing bean also injects the parameter bean(s). You can cut out the middlebean and inject the destination view's backing bean directly into the source view's backing bean, but that requires the destination bean to be session scope or higher. Otherwise it will be destroyed and replaced by a whole new bean instance (minus the parameter data) when you navigate to the destination view.
The IoC way of doing things can seem inside-out at first, but there are several advantages to it, which is why it is employed not only by JSF but also by other popular frameworks, such as Spring. In the traditional approach, the backing bean would have to know where to find stuff (Service Locator) and go out and get them. That requires coding platform-specific logic into the backing bean.
In IoC, the backing bean does nothing. The "bean wiring" mechanism handles the location of the required data automatically and it injects it automatically into the backing bean. Less coding, simpler coding, and the bean doesn't contain platform dependencies, so it can be implemented as a POJO. POJOs are desirable because they are easier to re-use and much easier to unit-test, since you don't have to establish an elaborate runtime environment (such as an HTTP container) to test the bean. And, it should be noted that while HTML and HTTP are the most common underpinnings for JSF apps, JSF itself is designed to be usable in other environments as well. Including environments where you don't have HttpServletRequest objects to yank parameters from.
The downside to this is pretty obvious, I think. Your "parameter beans" are, as I said, required to be session-scope or higher, since request scope beans cannot be injected into anything higher than request-scope target beans and View-scoped beans won't survive the transition to a new View. So if you don't want parameter beans living on long after they are no longer needed, you have to manually remove them from the session (I have a separate JSF utility class for platform-specific functions like that). Or you can attempt the new JSF2 Custom Scope, but in my opinion, that particular mechanism has some growing up to do before it's ready for prime-time. At the moment, documentation is less than sterling and the mechanisms themselves are pretty clunky.
Being persecuted doesn't in any way prove your righteousness or your beliefs. Many people get persecuted because they are repugnant or annoying. Or just because they can be.
JSF ViewScoped is used for ajax calls. Bean object will remain in scope as long as ajax call will be made within the context of a single page.
You can use any one of the following 2 approaches as per your requirement:
1) Use ajax call to update your page.
2) Use Conversation Scope. (In case of Conversation Scope, bean object will remain in scope as long as conversation is active.You can begin and end the conversation as per your need.)
my overalls have superpowers - they repel people who think fashion is important. Tiny ad: