0

我在 index.xhtml 中有 2 个 SelectOneMenu,如下所示。menu1 本质上选择一种语言(sp 或 en),而 menu2 显示可能的序列号(0 到 3)。我有初始化两个菜单上的默认值的初始化构造函数(后构造函数)。但是由于某些奇怪的原因,如果我为默认语言以外的语言选择默认序列号以外的序列号,则语言会以某种方式重置为初始默认值:(

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <title>My page</title>
    </h:head>
    <h:body>
                            <div>
                                <h4>Change Existing Description</h4>
                            </div>
                            <h:form id="myForm">
                                    <h:panelGrid columns="4">
                                        <h:outputLabel value="Language:" />
                                        <h:selectOneMenu value="#{myBean.language}">
                                            <f:selectItems value="#{myBean.languages}" />
                                            <f:ajax listener="#{myBean.doUpdate}" render ="myForm" />
                                        </h:selectOneMenu>
                                        <h:outputLabel value="SerialID:" />
                                        <h:selectOneMenu value="#{myBean.serialID}">
                                            <f:selectItems value="#{myBean.serialIDs}" />
                                            <f:ajax listener="#{myBean.doUpdate}" render ="myForm" />
                                        </h:selectOneMenu>

                                    </h:panelGrid>
                                </h:form>
    </h:body>
</html>

这是我的 Bean 代码。问题出在哪里??请指教!

package bean;



import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.Stateful;
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedBean;



@ManagedBean(name = "myBean")
//@Stateless
@Stateful
@RequestScoped
public class MyBean {

    public static final int PERMISSIONS = 2;
    private List<String> languages;
    private String language;
    private int serialID;
    private List<Integer> serialIDs;

    /**
     * init() method for initializing the bean. Is called after constuction.
     */

    @PostConstruct
    private void init() {
    //public MyBean () {
        languages = getAllLanguages();
        language = "en"; //defaultLanguage 
        serialID = 3;
        serialIDs = getSerialIDsFromOverview();
    } 

    public List<String> getLanguages() {
        System.out.println("getLanguages, language " +language);
        return languages;
    }


    public int getPERMISSIONS() {
        return PERMISSIONS;
    }

    public String getLanguage() {
        System.out.println("getLanguage " +language);
        return language;
    }

    public void setLanguage(String language) {
        System.out.println("setLanguage " +language);
        this.language = language;
    }


    public int getSerialID() {
        System.out.println("getSerialID " +serialID);
        return serialID;
    }

    public void setSerialID(int serialID) {
          System.out.println("setSerialID " +serialID);
        this.serialID = serialID;
    }

    public List<Integer> getSerialIDs() {
        System.out.println("getSerialIDs language =  "+language );
        return serialIDs;
    }

    public List<String> getAllLanguages() {
        List<String> results = new ArrayList<String>();
        results.add("sp");
        results.add("en");

        if(results != null){
            System.out.println("getting all languages");
        }
        return results;
    }


    public void doUpdate() {

         System.out.println("doUpdate language " +language);
         System.out.println("doUpdate serialID " +serialID);

    }

    /**
     * Returns a list of all serialIDs present in the overview.
     * @return 
     */
    private List<Integer> getSerialIDsFromOverview() {
        List<Integer> results = new ArrayList<Integer>();
        results.add(0);
        results.add(1);
        results.add(2);
        results.add(3);
        return results;
    }

}

更新:

在接受了cubbuk的建议后,我坐下来用 @ViewScoped 注释更正了我的代码,并使 bean 实现了可序列化。这行得通。然而,接下来我要做的是包含一个@EJB 注释来调用一个无状态bean,它调用实体管理器从数据库中获取序列ID,而不是“硬编码”它。那是我遇到问题的时候:不可序列化异常“ java.io.NotSerializableException: bean.__EJB31_Generated__。我该如何解决这个问题?当我将 myBean 返回到 RequestScope 并删除 Serializable 时,我可以毫无问题地运行代码,但是切换菜单的初始化值:(

顺便说一句,我检查了这篇文章:@ViewScoped 托管 bean 中的 @EJB 导致 java.io.NotSerializableException并将我的状态保存方法设置为服务器,但这给了我“来自服务器的响应”弹出消息:(请帮忙!

4

1 回答 1

1

由于您在每次请求后都使用@RequestScopedbean 作为支持 bean,因此您的init方法被调用并且您的值被重置。为避免这种情况,您需要使用@ViewScopedbean 作为支持 bean。我相应地更新了您的 bean,请注意您的支持 bean 现在实现了Serializable接口。这是必需的,因为此 bean 将存储在您的 servlet 中,如果内容不能保存在内存中,则需要将其刷新到磁盘。要了解@ViewScopedbean 的详细信息,请查看以下帖子:

http://balusc.blogspot.com/2010/06/benefits-and-pitfalls-of-viewscoped.html

除此之外,为了命名约定,我将 your getAllLanguagesandgetSerialIDsFromOverview方法重命名为initAllLanguagesand initSerialIdsas 以 get 和 set 开头的方法可能会令人困惑,因为它们主要用于 getter 和 setter。

最后,当您f:ajax默认使用命令时,UIInput将呈现并执行绑定到的 ajax 命令。由于您不h:selectOneMenu根据彼此的值刷新菜单,因此您不需要呈现整个表单。对于这种情况,以下内容就足够了:

<h:form id="myForm">
                                    <h:panelGrid columns="4">
                                        <h:outputLabel value="Language:" />
                                        <h:selectOneMenu value="#{myBean.language}">
                                            <f:selectItems value="#{myBean.languages}" />
                                            <f:ajax listener="#{myBean.doUpdate}"/>
                                        </h:selectOneMenu>
                                        <h:outputLabel value="SerialID:" />
                                        <h:selectOneMenu value="#{myBean.serialID}">
                                            <f:selectItems value="#{myBean.serialIDs}" />
                                            <f:ajax listener="#{myBean.doUpdate}"/>
                                        </h:selectOneMenu>

                                    </h:panelGrid>
                                </h:form>

@ManagedBean
@ViewScoped
public class MyBean implements Serializable
{

    public static final int PERMISSIONS = 2;
    private List<String> languages;
    private String language;
    private int serialID;
    private List<Integer> serialIDs;

    /**
     * init() method for initializing the bean. Is called after constuction.
     */
    @PostConstruct
    protected void init()
    {
        //public MyBean () {
        System.out.println("lang: " + language);
        System.out.println("serialId: " + serialID);
        System.out.println("init is called");
        initAllLanguages();
        initSerialIds();
        language = "en"; //defaultLanguage 
        serialID = 3;
    }

    public List<String> getLanguages()
    {
        return languages;
    }

    public int getPERMISSIONS()
    {
        return PERMISSIONS;
    }

    public String getLanguage()
    {
        return language;
    }

    public void setLanguage(String language)
    {
        this.language = language;
    }

    public int getSerialID()
    {
        return serialID;
    }

    public void setSerialID(int serialID)
    {
        this.serialID = serialID;
    }

    public List<Integer> getSerialIDs()
    {
        return serialIDs;
    }

    private void initAllLanguages()
    {
        languages = new ArrayList<String>();
        languages.add("sp");
        languages.add("en");
    }

    public void doUpdate()
    {

        System.out.println("doUpdate language " + language);
        System.out.println("doUpdate serialID " + serialID);

    }

    /**
     * Returns a list of all serialIDs present in the overview.
     *
     * @return
     */
    private void initSerialIds()
    {
        serialIDs = new ArrayList<Integer>();
        serialIDs.add(0);
        serialIDs.add(1);
        serialIDs.add(2);
        serialIDs.add(3);
    }
}

干杯

于 2013-02-04T14:50:16.203 回答