Data from @RequestScoped bean is shared in differe

2020-02-13 01:35发布

问题:

I have a @RequestScoped bean with a List property.

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
}

This property is linked to a datatable:

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

The List is dynamically filled with no problem, and the datatable is displayed with no problems. But if, I navigate to another page, and then go back to the initial page the datatable is still with the data of the initial request. It shouldn't be empty again? If the bean is request scoped it should be destroyed after the request, and I should get and empty datatable as the beginning.

Even more strange is that if I open the page in one browser (like Firefox), fill the datatable with a request, then I open another browser (like Chrome) and go to the datatable page, it is filled with the data from previous request from another browser! I think the bean is behaving like an application one.

Any ideas?


Update 1: The class is not static neither its variables. Also, I disable tomcat cache, but still not working.

Update 2: I think probably found the problem. My backing beans are annotated with @Controller from Spring. I use this annotation because then use @Autowired to bind services. Could be this is creating a singleton and that why is not being created and destroyed with every request? I think pretty sure the problem is in the mix of Spring and JSF2 annotations.

回答1:

You shouldn't manage a single bean by multiple different bean management frameworks like JSF, CDI and Spring. Choose the one or the other. When managing the bean by for example Spring's @Controller, all bean management related annotations of other frameworks like JSF's @ManagedBean and CDI's @Named are ignored.

I don't do Spring and I have no idea why you're using it instead of the standard Java EE 6 API, but the symptoms and documentation indicates that the scope of such a Spring bean indeed defaults to the application scope. You need to specify the bean scope by Spring @Scope annotation. You would also like to remove the JSF bean management annotations since they have no value anymore anyway and would only confuse the developer/maintainer.

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

Alternatively, you can also get rid of Spring @Controller annotation and stick to JSF @ManagedBean. You can use @ManagedProperty instead of @Autowired to inject another @ManagedBean instance or even a Spring managed bean (if you have Spring Faces EL resolver configured), or the Java EE standard @EJB to inject an @Stateless or @Stateful instance.

E.g.

@ManagedBean
@RequestScoped
public class MyBean implements Serializable {

    @EJB
    private SomeService service;

    // ...
}

See also:

  • Spring JSF integration: how to inject a Spring component/service in JSF managed bean?