JSF 2.0注入具有不同范围的托管bean

Syd*_*ney 4 jsf jsf-2

我有一个无状态的控制器,负责处理表格.这被定义为ApplicationScoped.在我的页面上,我有一个与支持bean关联的表单定义为a ViewScoped.

我想处理表单时遇到的错误:

serverError: class com.sun.faces.mgbean.ManagedBeanCreationException Unable to create managed bean myController.  The following problems were found:
     - The scope of the object referenced by expression #{myFormBean}, view, is shorter than the referring managed beans (myController) scope of application
Run Code Online (Sandbox Code Playgroud)

在我的形式:

       Name: <h:inputText value="#{myFormBean.name}" id="name" />
        <h:commandButton value="Save Name" action="#{myController.processForm}">
            <f:ajax render="nameResult" />
        </h:commandButton>
       Your name is <h:outputText value="#{myFormBean.name}" id="nameResult"/>
Run Code Online (Sandbox Code Playgroud)

控制器:

@ManagedBean
@ApplicationScoped
public class MyController {
    @ManagedProperty("#{myFormBean}")
    private MyFormBean myBean;
    public void processForm() {
        System.out.println(myBean.getName());
        // Save current name in session
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(
                "name", myBean.getName());
    }
}
Run Code Online (Sandbox Code Playgroud)

支持bean:

@ManagedBean
@ViewScoped
public class MyFormBean {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以通过将控制器设置为SessionScoped来解决这个问题,但由于控制器是无状态的,所以它不是一种干净的方式,因此我不需要为每个会话使用一个控制器.整个应用程序的一个控制器就足够了.

我有一个Spring MVC背景,这就是为什么我对如何使用JSF 2.0做事感到困惑

Bal*_*usC 11

您的设计存在缺陷.您的控制器根本不是无状态的.它有一个不同的属性,每个请求/视图,即myBean.如果它受支持,则每个新请求/视图将覆盖先前设置的请求/视图,并且最终用户将面对完全不同的最终用户的属性值.这导致高并发情况下的问题.

您需要使其请求/视图作用域而不是应用程序作用域.然而,我相信你必须完全不同.您在action方法中手动设置会话范围中的属性,而不是将其设置为(注入)会话范围bean的属性.如何正确地解决它取决于功能要求,这个问题不明确.