How can I set a bean property when the page is loading in jsf? - jsf

In my project, I am using myfaces 1.2, rich faces 3.3.3 and spring 2.5 for backing beans. I searched over Internet for this simple need all weekend but I couldn't managed to set the bean property. h:inputhidden trick is good for calling a bean function. But I couldn't use this to set the property. For instance I want to set a bean property named as "number" to "1" when a page is loading.
Over internet I saw these was being used to set the bean property. I am new in web programming and I don't know how these working.. But maybe these make you remember something.
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
request.getParameter()
<h:inputhidden>
Updated:
I want to set the value from the page not in bean. so I must get the value from the page. I will set the bean property differently in different pages. and I am using one bean for multiple page.

You can use:
<f:view before="#{bean.beforePhaseMethod}"> (if using facelets it's called beforePhase)
a #PostConstruct method for request-scoped beans
if there is no logic, simply give an initial value of the field private int foo = 1

Related

How ManagedBeans figure out to which facelet or xhtml file they belong?

In JSF, I wonder how a ManagedBean understands that it should be available to an xhtml or facelet ?
To bind component values and objects to managed bean properties or to reference managed bean methods from component tags, page authors should use the Expression Language syntax.
When user make request to the page that contains EL, that refers to specific manage bean, this bean will be instantiated by JSF framework (except managed beans that have attribute eager="true", that means that managed bean is created before it is requested for the first time).
So the fact is that managed bean will be instantiated by JSF container and works as a model for the appropriate UI Component so the Facelet will know about the Bean, not vice versa

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 Managed bean and managed property both necessary?

I'm new to JSF and was wondering:
If I have a controller that handles all the work for a given page and a bean that holds all the data for said page, is It necessary to have both the
#ManagedProperty(value="#{myBean}")
annotation on the controller and the
#ManagedBean(name="myBean")
#SessionScoped
annotations on the form bean?
Managed beans in JSF are used to store the state of a web page. The JSF implementation is responsible for creating and discarding the bean objects( hence the name managed bean).
For every class you write #ManagedBean, the bean object is created by the JSF implementation as and when it detects an usage of the bean with the name(you can either sepcify a bean name or leave it to JSF to use the default name-class name with the first character changed to lowercase). The object created is placed in a map of the specified scope. Each scope has a map that it uses to store bean objects which have that scope specified.
Now if you need the values of these beans in your controller, you have to inject it using the ManagedProperty annotation. Note that you would need to provide the controller with a setter method for the managedProperty.
So to answer your question, the managedBean annotation is required to tell the JSF implementation to manage the bean instance and store the values in the table specific to the session scope. And the ManagedProperty annotation is needed to use that bean stored in the current session so that you can access all of its values.
We use #ManagedBean annotation to register a java bean with a JSF framework. This is a replacement for a faces-config.xml <managed-bean> element. We typically do not use name attribute because it already defaults to a simple class name camel cased.
We use #RequestScope and other scope annotations to explicitly specify the scope we want via annotation. This is equivalent to specifying<managed-bean-scope> xml entry. If you don't specify the scope it will be defaulted to #NoneScoped.
We use #ManagedProperty and specify an EL-expression in its value attribute to use JSF-provided dependency injection engine for JSF artifacts like other managed beans with broader scopes and EL-defined variables like param. We do it in case we need the injected values in other JSF artifacts, most typically beans. The injected values are available in bean's #PostConstruct-annotated method. This is an alternative to <managed-property> xml entry.
To sum it up. Use #ManagedBean #RequestScoped to register a bean with JSF framework. Use #ManagedProperty inside this bean to be able to reference among others other JSF beans with the same or broader scopes in this bean. In case you don't need to reference other beans in the created bean you don't need to use the #ManagedProperty annotation as it's purely optional.

View-scoped bean recreated on POST when URL parameters not used

I have a view-scoped JSF-managed bean that's backing an xhtml view where I read one parameter from the URL using f:viewParam.
The view presents a form to the user. However, when the user submits the form by pressing the p:commandButton it seems that the view-scoped bean is recreated (I added a #PostConstruct annotation to verify this) and so doesn't remember the instance variable read from the f:viewParam (invId in the code below).
I originally navigate to the view with a GET that includes a URL parameter but the POST message that's send when the user presses the p:commandButton doesn't include the URL parameter. So I am thinking that when the JSF runtime doesn't see the URL parameter on the POST it considers this to be a different view and is recreating the JSF-managed bean. When I change the view scope to session-scoped the code works.
Here's the code:
view
<f:metadata>
<f:viewParam name="invId" value="#{registerBean.invId}"/>
</f:metadata>
<h:form id="registrationForm">
....
<p:commandButton value="register" action="#{registerBean.register}"
icon="ui-icon ui-icon-newwin" ajax="false"/>
</h:form>
backing bean
#ManagedBean
#ViewScoped
public class RegisterBean implements Serializable {
#ManagedProperty(value="#{invId}")
private String invId;
...
update
It turns out that this wasn't related to the URL parameters at all. Following BalusC advice below I removed the c:when tags my view was using (relying on rendered attributes instead for the same effect), and now the view-scoped bean is no longer recreated and the invId field is properly retained.
The problem is not visible in the code posted so far, but it's for JSF 2.0/2.1 a known issue that a view scoped bean will be recreated when one of its properties is been bound to an attribute of a taghandler like JSTL <c:if> or Facelets <ui:include> or a view build time attribute of JSF component, such as id and binding, while partial state saving is enabled (as by default).
The background explanation is that any EL expressions in those attributes are executed during building and restoring the view. As view scoped beans are stored in the view and thus only available after restoring the view, such an EL expression evaluation would cause a brand new and separate view scoped bean to be created. This is basically a chicken-egg issue. It's fixed in the upcoming JSF 2.2.
There are basically 3 solutions:
Change the view accordingly so that those EL expressions are only evaluated during view render time. E.g. replace <c:if>/<c:choose> by rendered.
Or bind those attributes to a request scoped bean (design notice: you can just inject a view scoped bean as a managed property of a request scoped bean).
Turn off partial state saving, if necessary only for the particular view.
See also:
JSTL in JSF2 Facelets... makes sense?
#ViewScoped fails in taghandlers

Difference between Apply Request Values and Update Model Values

I often get doubt on these two phases. The following is my understanding:
Apply Request Values
In this phase, the submitted values are coming from the request parameter. Then the request values are set into the backing bean ie.setting to components UIInput
Update Model Values
In this phase, processed values are transferred from backing bean (UIInput) to managed beans. (It is our custom defined JSF beans).
I am thinking that my understanding is correct. But, reading few articles made me confused. I want to make me more clear on these two phases. Please clarify me.
Apply Request Values
In this phase, the submitted values are coming from the request parameter. Then the request values are set into the backing bean ie.setting to components UIInput
That's not entirely correct. The values are not set into backing beans. They are set into components. Basically the following happens for each UIInput component in the component tree:
input.setSubmittedValue(request.getParameter(input.getClientId()));
Here input is UIInput and request is HttpServletRequest.
Update Model Values
In this phase, processed values are transferred from backing bean (UIInput) to managed beans. (It is our custom defined JSF beans).
Also not entirely correct. UIInput components are not backing beans. Basically the following happens for each UIInput component in the component tree:
bean.setProperty(input.getValue());
Here, the bean and property is based on the input's valuebinding, e.g. value="#{bean.property}".
All with all, your confusion is clearly in distinguishing between the JSF component tree, the JSF backing beans and the JSF managed beans. The JSF component tree is the one which you've definied in the JSP/Facelets page and as you can obtain by FacesContext#getViewRoot(). The JSF backing beans are Javabean classes whose properties are bound to the component tree using EL such as #{bean.property}. The JSF managed beans are concrete instances of those Javabean classes. They can be request, session or application scoped (and in JSF 2.0 also view scoped). It are the managed beans where the values are actually been set and retrieved.
See also
Debug JSF lifecycle

Resources