3

我有一个@RequestScoped带有List属性的bean。

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.springframework.stereotype.Controller;

@Controller
@ManagedBean
@RequestScoped
public class MyBean implements Serializable {

    private List list;

    // getters and setters
}

此属性链接到数据表:

<ice:dataTable value="#{myBean.list}" ..other stuff.. />

List动态填充没有问题,数据表显示没有问题。但是,如果,我导航到另一个页面,然后返回到初始页面,数据表仍然包含初始请求的数据。它不应该又是空的吗?如果 bean 是请求范围的,它应该在请求之后被销毁,我应该得到并清空数据表作为开始。

更奇怪的是,如果我在一个浏览器(如 Firefox)中打开页面,用请求填充数据表,然后我打开另一个浏览器(如 Chrome)并转到数据表页面,它会填充来自先前请求的数据从另一个浏览器!我认为 bean 的行为类似于应用程序。

有任何想法吗?


更新 1:该类既不是静态的,也不是它的变量。另外,我禁用了tomcat缓存,但仍然无法正常工作。

更新2:我想可能发现了问题。@Controller我的 backing bean 是用Spring注释的。我使用这个注解是因为然后用于@Autowired绑定服务。这可能是在创建一个单例,为什么没有在每个请求中创建和销毁?我认为很确定问题出在 Spring 和 JSF2 注释的混合中。

4

1 回答 1

4

您不应该通过多个不同的 bean 管理框架(如 JSF、CDI 和 Spring)来管理单个 bean。选择一个或另一个。例如,当通过 Spring 管理 bean 时@Controller,其他框架(如 JSF@ManagedBean和 CDI)的所有与 bean 管理相关的注释@Named都将被忽略

我不使用 Spring,我不知道您为什么使用它而不是标准的 Java EE 6 API,但是症状和文档表明这种 Spring bean 的范围确实默认为应用程序范围。您需要通过 Spring@Scope注解指定 bean 范围。您还想删除 JSF bean 管理注释,因为它们已经没有任何价值,只会让开发人员/维护人员感到困惑。

@Controller
@Scope("request")
public class MyBean implements Serializable {
    // ...
}

或者,您也可以摆脱 Spring@Controller注释并坚持 JSF @ManagedBean。您可以使用@ManagedProperty而不是@Autowired注入另一个@ManagedBean实例甚至是 Spring 托管 bean(如果您配置了 Spring Faces EL 解析器),或者使用 Java EE 标准@EJB来注入一个@Stateless@Stateful实例。

例如

@ManagedBean
@RequestScoped
public class MyBean implements Serializable {

    @EJB
    private SomeService service;

    // ...
}

也可以看看:

于 2012-05-07T18:52:12.413 回答