I have a report generation page where I have few filters like countryId
, Date
and few other parameters for the user to select. Now based on the chosen parameters, there is a database call which uses these parameters to fetch a result list .
Now the managed bean contains all these search parameters and the result list .Let us name this bean as Bean1
public class Bean1 implements Constants{
private List<SelectItem> countryList;
private List<String> choosenCountryList;
private List<String> choosenProgramList;
private String invoiceDatePriorTo= CalendarUtilities.getTodaysDate() ;
private List<CustomResults> searchResultList
}
We have one more managed bean Bean2
which contains a property of Bean1
public class Bean2 implements Constants {
private Bean1 bean1;
public getSearchResults(){
//Code for fetching the search list for bean 1
this.setsearchResultList() //=fetched list from DB;
}
public modifySearchResults(){}
}
Now when on the trigger of an action from the JSF page we call the getSearchResults()
method and we set the searchResultList
to be displayed in the screen .In this way we are able to display the search list on screen
Now the list we get is subjected to user modification on screen .Now when we again call the modifySearchResults to edit the list we are not able to retrieve the list in the bean2 because the managed bean is in request scope .
Can anyone tell me how to go ahead and solve this problem?
The scope of the managed bean is declared using one of NoneScoped , RequestScoped , ViewScoped , SessionScoped , ApplicationScoped , or CustomScoped annotations. If the scope annotations are omitted, the bean must be handled as if the RequestScoped annotation is present.
1) BB: A backing bean is any bean that is referenced by a form. MB: A managed bean is a backing bean that has been registered with JSF (in faces-config. xml) and it automatically created (and optionally initialized) by JSF when it is needed.
ApplicationScope: The application scope persists for the entire duration of the web application. That scope is shared among all requests and all sessions. You place managed beans into the application scope if a single bean should be shared among all instances of a web application.
You can specify one of the following scopes for a bean class: Application (@ApplicationScoped): Application scope persists across all users' interactions with a web application. Session (@SessionScoped): Session scope persists across multiple HTTP requests in a web application.
According to this page: Accessing one managed bean from another
How can I access one Managed Bean from another?
There are two ways for one managed bean to access another managed bean in the same web app:
Using dependency injection
Using JSF 2 @ManagedProperty
annotation:
In your managed bean add a @ManagedProperty
annotation to the related property and don't forget to add getter and setter methods.
@ManagedBean(name = "usingBean")
@RequestScoped
public class UsingBean {
@ManagedProperty(value = "#{neededBean}")
private NeededBean neededBean;
public NeededBean getNeededBean() {
return neededBean;
}
public void setNeededBean(NeededBean neededBean) {
this.neededBean = neededBean;
} // .... }
Binding through faces-config.xml
: in your project's faces configuration file which defines the managed beans, a managed bean property can be declared as initialised with a reference to another managed bean:
<managed-bean>
<managed-bean-name>neededBean</managed-bean-name>
<managed-bean-class>fqn.to.NeededBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>usingBean</managed-bean-name>
<managed-bean-class>fqn.to.UsingBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>neededBean</property-name>
<value>#{neededBean}</value>
</managed-property>
</managed-bean>
The constraints are that:
Using Lookup
The following java code can be used in MyFaces 1.1 to explicitly look up an arbitrary managed bean by name:
FacesContext facesContext = FacesContext.getCurrentInstance();
NeededBean neededBean = (NeededBean) facesContext.getApplication()
.getVariableResolver().resolveVariable(facesContext, "neededBean");
In MyFaces 1.2, that code is deprecated, and preferred version is:
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
NeededBean neededBean = (NeededBean) FacesContext.getCurrentInstance().getApplication()
.getELResolver().getValue(elContext, null, "neededBean");
Alternately, you can use this code to evaluate any JSF EL expression.
FacesContext facesContext = FacesContext.getCurrentInstance();
NeededBean neededBean = (NeededBean)facesContext.getApplication()
.createValueBinding("#{neededBean}").getValue(facesContext);
Just declare your dataBean as ManagedProperty
.
From the tagging I assume it's about JSF2.0.
You need to declare bean1
as managed property in bean2
.
It should look like
@ManagedBean
public class Bean1{
}
and
@ManagedBean
public class Bean2{
@ManagedProperty(value="#{bean1}")
Bean1 bean1;
//setter & getter of bean1
}
See Also
Well you said it yourself. You have to move the bean from the RequestScope
.
Depending of your application you may want to use:
@SessionScoped
@ViewScoped
Here you can find an article about choosing the right scope.
Second of all you may want to use Dependency Injection. JSF has the nice @ManagedProperty
. You can read more about it here.
EDIT
Seeing now that you don't want to use the Session another solution which comes to my mind is the following:
@ManagedBean
@ViewScoped
public class Bean1 implements Constants{
private List<SelectItem> countryList;
private List<String> choosenCountryList;
private List<String> choosenProgramList;
private String invoiceDatePriorTo= CalendarUtilities.getTodaysDate() ;
private List<CustomResults> searchResultList
public getSearchResults(){
// Your code here
}
public modifySearchResults(){
// Your code here
}
}
As you said the problem is that you can't save all the information from one request to the next. Usually this is a case when normally the @ApplicationScoped
or @ViewScoped
is used. For different reasons this may not be the best solution in some cases.
For your example placing all the methods in one bean which is @ViewScoped
may be the best solution. This approach comes with its drawbacks but I think this is as good as it gets..
Here you can read more about this matter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With