访问JSF托管bean中的值在另一个托管bean中

10

我有一个报告生成页面,其中有一些过滤器,如countryIdDate和其他一些参数供用户选择。现在根据所选择的参数,有一个数据库调用使用这些参数来获取结果列表。

现在托管的 bean 包含所有这些搜索参数和结果列表。让我们将此 bean 命名为 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
}

我们还有一个托管Bean Bean2,其中包含一个属性 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(){}
}

现在,在由JSF页面触发操作时,我们调用getSearchResults()方法,并将searchResultList设置为在屏幕上显示。通过这种方式,我们能够在屏幕上显示搜索列表。

现在,我们得到的列表受用户在屏幕上的修改影响。当我们再次调用modifySearchResults以编辑列表时,由于托管bean处于请求范围内,因此无法在bean2中检索列表。

有人可以告诉我如何解决这个问题吗?

4个回答

11

只需将你的dataBean声明为ManagedProperty

从标记中我猜测这是关于JSF2.0的。

你需要在bean2中声明bean1作为托管属性。

它应该像这样:

@ManagedBean
public class Bean1{
}

并且

@ManagedBean
public class Bean2{

  @ManagedProperty(value="#{bean1}") 
  Bean1 bean1;
  //setter & getter of bean1

}

另请参阅


你能详细说明一下你想让我做什么吗? - Sam
Jigar,感谢你的回复,但我已经将其添加到facesconfig.xml中了。 - Sam
<managed-bean> <managed-bean-name>bean1</managed-bean-name> <managed-bean-class>com.bean.Bean1</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>bean2</managed-bean-name> <managed-bean-class>com.action.Bean2</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>bean1</property-name> <property-class>com.bean.Bean1</property-class> <value>#{bean1}</value> </managed-property> </managed-bean> - Sam
我在你的bean中没有看到setter/getter。 - jmj

4

你自己说了,你必须将bean从RequestScope中移动。

根据你的应用程序,你可能想使用:

  • @SessionScoped
  • @ViewScoped

这里有一篇关于选择正确作用域的文章。

其次,你可能想使用依赖注入。JSF有很好的@ManagedProperty。你可以在这里阅读更多信息。

编辑

现在看到你不想使用Session的解决方案之一是:

@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
    }
}

如您所说,问题是您无法将一个请求中的所有信息保存到下一个请求中。通常这种情况下应使用@ApplicationScoped@ViewScoped。但因为某些原因,在某些情况下这可能不是最好的解决方案。
对于您的示例,将所有方法放在一个@ViewScoped bean中可能是最佳解决方案。这种方法有其缺点,但我认为这已经是最好的方法了。 这里可以阅读更多相关内容。

我不想使用会话范围..还有其他方法吗? - Sam
@Sam 嗯,我认为你可以用不同的方法来解决这个问题。将 getSearchResults() 放在 Bean1 中,并用 @ViewScoped 注释此 bean。这样,只要您不更改视图,就能访问所有信息。 - Ionut

1
根据这个页面:访问另一个托管Bean 如何访问一个托管Bean中的另一个托管Bean?
有两种方法可以让一个托管Bean在同一个Web应用程序中访问另一个托管Bean:
1.使用依赖注入
2.使用JSF 2 @ManagedProperty 注释:
在您的托管Bean中添加一个@ManagedProperty注释到相关属性上,不要忘记添加getter和setter方法。
@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;
    } // .... }

通过 faces-config.xml 进行绑定:在项目的 faces 配置文件中定义托管 bean 时,可以声明将托管 bean 属性初始化为对另一个托管 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>

以下是限制条件:

  • 使用的bean必须具有与所需bean相同或更短的范围
  • 使用的bean必须具有一个以所需bean为参数的属性设置方法
  • 这些bean不能相互依赖

使用查找

在MyFaces 1.1中,可以使用以下Java代码通过名称显式查找任意托管bean:

FacesContext facesContext = FacesContext.getCurrentInstance(); 
NeededBean neededBean = (NeededBean) facesContext.getApplication()
.getVariableResolver().resolveVariable(facesContext, "neededBean");

在MyFaces 1.2中,该代码已被弃用,推荐使用以下版本:

ELContext elContext = FacesContext.getCurrentInstance().getELContext(); 
NeededBean neededBean = (NeededBean) FacesContext.getCurrentInstance().getApplication() 
.getELResolver().getValue(elContext, null, "neededBean");

此外,您可以使用以下代码来评估任何JSF EL表达式。

FacesContext facesContext = FacesContext.getCurrentInstance(); 
NeededBean neededBean = (NeededBean)facesContext.getApplication() 
.createValueBinding("#{neededBean}").getValue(facesContext); 

-1

这个链接已经失效了。因此不推荐只回答带有链接的问题。 - Luciano Brum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接