JSF #ViewScoped - #Postconstruct called multiple times [duplicate] - jsf

What does the view scope mean? Can anyone explain about it, so that I can understand how it differs from the request scope?

A #ViewScoped bean lives exactly as long as a JSF view. It usually starts with a fresh new GET request, or with a navigation action, and will then live as long as the enduser submits any POST form in the view to an action method which returns null or void (and thus navigates back to the same view). Once you refresh the page, or return a non-null string (even an empty string!) navigation outcome, then the view scope will end.
A #RequestScoped bean lives exactly as long a HTTP request. It will thus be garbaged by end of every request and recreated on every new request, hereby losing all changed properties.
A #ViewScoped bean is thus particularly more useful in rich Ajax-enabled views which needs to remember the (changed) view state across Ajax requests. A #RequestScoped one would be recreated on every Ajax request and thus fail to remember all changed view state. Note that a #ViewScoped bean does not share any data among different browser tabs/windows in the same session like as a #SessionScoped bean. Every view has its own unique #ViewScoped bean.
See also:
How to choose the right bean scope?
The benefits and pitfalls of #ViewScoped

Related

Does JSF prevent calls to unrendered managed bean actions by tampered requests

A method in a managed bean is protected by JSF? See the code:
Managed Bean
#ManagedBean
public class My {
public void test() {
System.out.println("called");
}
}
XHTML
<h:form>
<h:commandButton rendered="true" action="#{my.test}" value="Teste" />
</h:form>
If the button is not rendered (rendered="false"), a HTTP POST request (as the button would do) can be done and call the test() method?
In other words, JSF prevents calls to managed beans methods by tampered requests?
In other words, JSF prevents calls to managed beans methods by tampered requests?
Yes.
JSF re-evaluates the component's rendered attribute during apply request values phase. If it's false, then in case of UICommand components the ActionEvent simply won't be queued, regardless of whether the (tampered) HTTP request parameter indicates that the button is being pressed.
JSF has similar safeguard against tampered requests on the disabled and readonly attributes, also those of UIInput components. And, in UISelectOne/UISelectMany components, JSF will validate if the submitted value is indeed part of the provided available options.
JSF does this all also with help of the view state. If JSF were stateless, there would be more risk that one or other may fail if those attributes suddenly become request scoped instead of view scoped.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated - point 5
Validation Error: Value is not valid
How to disable/enable JSF input field in JavaScript?
What is the usefulness of statelessness in JSF?

How to instantiate a backing bean on page load

For a project we are migrating some java applications to WebSphere 8.5. In the process we are trying to get rid of some legacy frameworks. One of them is shale (apache attic). The only component from shale that is used is the view controller to instantiate a request scoped jsf managed beans for every page. Every bean has an init method that is called on page load. I'd like to use #PostConstruct on this method. The only problem I have that the bean gets instantiated when a method on the bean is called. Unfortunately the bean is not always called and the init method does populate data on a session scoped bean. There is a naming convention that links pages and beans so we could use a listener to instantiate the bean based on the request. Another solution might be changing the scope to viewscope (probably to much a hassle on websphere 8.5).
I was wondering if there is something I can do to make the PostConstruct work? And are there other options I'm missing?
edit:
I have a PhaseListener in place that performs the basic functionality. It matches the requested page to the corresponding bean (by naming convention). The following is used to instantiate the bean but it looks a bit ugly.
expressionFactory.createValueExpression(elContext, "#{" + managedBeanName + "}", Object.class)
Is there a more elegant way to do this?
Perhaps you could try using <f:event/> ?
In your view, you could add this to the page.
<f:event type="postAddToView" listener="#{backingBean.myInitMethod()"/>
https://stackoverflow.com/a/14004230/4706826
Gives you info on when the events get executed.
Put a #PostConstruct annotated method in the backing bean. This annotation tells the bean to execute the annotated method every time its constructor is being called.
Example:
#ManagedBean
#ViewScoped
public class MyManagedBean{
#PostConstruct
public void initView() throws Exception{
...initialize page values, execute database queries, etc.
}

JSF 2.0 Managed Property object has two different instances, when I to open page and to do ajax request

all
I novice in JSF2 (used Mojarra + primeFaces on tomcat7) and I get strange behavior of ManagedProperty object:
#ManagedBean
#ViewScoped
public class CreateFactMB implements Serializable{
#ManagedProperty(value="#{collectionFactTable}")
private CollectionFactTable collectionFactTable; //SessionBean
...
//setters/getters
I printed object when I open page (refresh brouser) I see one instance of collectionTree
mbeans.CollectionFactTable#12803ba
But when I do ajax request
<p:commandButton id="btn1" value="Save" update="growl"
actionListener="#{createFactMB.doUpdate}" />
In doUpdate I see another instance of my collectionTree
mbeans.CollectionFactTable#625c49
It's problem because I can not do change while ajax action (because I have just copy)
Anybody can help me? What I'M doing not right?
I think you have a misunderstanding of how SessionScoped persistence works in JSF. This behavior is expected and normal.
At the beginning of the request all of the managed beans are instantiated regardless of scope. In the Restore View phase, the session based persistence values are set to the new managed bean object, effectively restoring the SessionScoped bean back to its last state before the last Response was sent.
Once the Response is complete and has been sent the data in these managed bean instances is persisted and the objects dereferenced for garbage collection. The process begins anew at the next request, regardless if it is Ajax or not.

JSF 1.2: How to keep request scoped managed bean alive across postbacks on same view?

Is it possible to keep a request scoped bean alive across postbacks on the same page?
The general problem is, as the bean gets trashed on end of request and recreated on every form submit, for example the booleans behind dynamically manipulated disabled, readonly and rendered get reset to their default values and cause the forms to not work as intented anymore.
I'll assume that the session scope is not an option, otherwise this question makes little sense.
You can do it using Tomahawk <t:saveState>. Add the following line somewhere to the page:
<t:saveState value="#{bean}" />
RichFaces <a4j:keepAlive> does also the same:
<a4j:keepAlive beanName="#{bean}" />
Or if there is room, upgrade to at least JSF 2.x and put the bean in view scope:
#ManagedBean
#ViewScoped
public class Bean implements Serializable {
// ...
}
Regardless of the way, the same bean will be there when you postback to the same view and keep returning null or void from action methods.
See also:
How to choose the right bean scope?
Difference between View and Request scope in managed beans
Not really, unless you store the Bean somewhere e.g. a Map in application scope, to retrieve it later.
Why not just make it Session scoped? This is what Session scope is there for, so multiple Requests during the same Session can hit the same state.

Difference between View and Request scope in managed beans

What does the view scope mean? Can anyone explain about it, so that I can understand how it differs from the request scope?
A #ViewScoped bean lives exactly as long as a JSF view. It usually starts with a fresh new GET request, or with a navigation action, and will then live as long as the enduser submits any POST form in the view to an action method which returns null or void (and thus navigates back to the same view). Once you refresh the page, or return a non-null string (even an empty string!) navigation outcome, then the view scope will end.
A #RequestScoped bean lives exactly as long a HTTP request. It will thus be garbaged by end of every request and recreated on every new request, hereby losing all changed properties.
A #ViewScoped bean is thus particularly more useful in rich Ajax-enabled views which needs to remember the (changed) view state across Ajax requests. A #RequestScoped one would be recreated on every Ajax request and thus fail to remember all changed view state. Note that a #ViewScoped bean does not share any data among different browser tabs/windows in the same session like as a #SessionScoped bean. Every view has its own unique #ViewScoped bean.
See also:
How to choose the right bean scope?
The benefits and pitfalls of #ViewScoped

Resources