Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing values of a JSF managed bean in another managed bean

Tags:

jsf

jsf-2

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?

like image 721
Sam Avatar asked Mar 07 '12 12:03

Sam


People also ask

Which one is a bean scope in JSF managed bean?

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.

What is the difference between managed bean and backing bean?

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.

Which scope is used on managed beans which is created for every session?

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.

What are the available scopes for the managed bean?

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.


3 Answers

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:

  • the using bean must have scope which is the same as or shorter than the needed bean
  • the using bean must have a property-setter method which takes the needed bean as a parameter
  • the beans cannot have managed dependencies on each other

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); 
like image 65
JoseJC Avatar answered Oct 20 '22 08:10

JoseJC


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

  • A nice article with example
like image 39
jmj Avatar answered Oct 20 '22 09:10

jmj


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.

like image 45
Ionut Avatar answered Oct 20 '22 09:10

Ionut