JSF @ViewScoped Bean状态丢失 [英] JSF @ViewScoped Bean State is Lost

查看:49
本文介绍了JSF @ViewScoped Bean状态丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将@ViewScoped Bean用于小型CRUD应用程序,我有一个编辑和查看页面,但是当我单击按钮(编辑)时,它将呈现编辑表单.编辑表单出现后,保存按钮或取消按钮不会调用该函数,而是呈现整个页面.根本不调用actionListener的函数,并且一切都已初始化.我的bean和页面有问题吗?我正在将JSF 2与richfaces和facelet一起使用.

I am using @ViewScoped Bean for small CRUD application I have a edit and view page but when I click buttons (edit) it will render edit form. After edit form appears the save button or cancel button does not call the function but renders the whole page. The actionListener's function is not called at all and everthing is initialized. Is something wrong with my bean and page?? I am using JSF 2 with richfaces and facelet.

          //ViewScoped Bean   

            /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package com.legendMgr.Legend;

    import java.io.Serializable;
    import java.sql.SQLException;
    import java.util.List;


    import java.util.logging.Logger;
    import javax.annotation.PostConstruct;

    import javax.faces.application.FacesMessage;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;

import javax.faces.context.FacesContext;

/**
 *
 * @author kitex
 */
@ManagedBean(name = "legendbean")
@ViewScoped
public class LegendController implements Serializable {

    LegendDTO legendDTO;
    String selectedLegend;
    List<LegendDTO> legendDTOs;
    boolean edit;

    public List<LegendDTO> getLegendDTOs() {
        return legendDTOs;
    }

    public void setLegendDTOs(List<LegendDTO> legendDTOs) {
        this.legendDTOs = legendDTOs;
    }

    @PostConstruct
    void initialiseSession() {
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
    }

    public LegendController() {
        if (!edit) {
            legendDTO = new LegendDTO();
            legendDTO.getList().add(new Legend());
            legendDTOs = getLegends();
        }
    }


    public String getSelectedLegend() {
        return selectedLegend;
    }

    public void setSelectedLegend(String selectedLegend) {
        this.selectedLegend = selectedLegend;
    }

    public boolean isEdit() {
        return edit;
    }

    public void setEdit(boolean edit) {
        this.edit = edit;
    }

    public LegendDTO getLegendDTO() {
        return legendDTO;
    }

    public void setLegendDTO(LegendDTO legendDTO) {
        this.legendDTO = legendDTO;
    }

    public void addLegendRange() {
        Logger.getLogger(LegendController.class.getName()).warning("List Size " + legendDTO.getList().size());
        legendDTO.getList().add(new Legend());
        Logger.getLogger(LegendController.class.getName()).warning("List Size " + legendDTO.getList().size());

    }

    public void removeLegendRange(Legend legend) {
        if (legendDTO.getList().size() != 1) {
            legendDTO.getList().remove(legend);
        }
    }

    public String saveLegend() {
        Logger.getLogger(LegendController.class.getName()).warning("Save Legend Edit" + edit);
        LegendDAO dao = new LegendDAO();
        if (dao.addLegend(legendDTO, edit)) {
            edit = false;
            Logger.getLogger(LegendController.class.getName()).warning("Save Legend Edit" + edit);
        } else {

            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Could Not Save Confim if you have already defined Legend " + legendDTO.getLegendName() + "!"));
        }
        return "";
    }

    public String cancel() {
        edit = false;
        legendDTO = new LegendDTO();
        legendDTO.getList().add(new Legend());
         return "";
    }

    public List<LegendDTO> getLegends() {
        LegendDAO dao = new LegendDAO();
        return dao.getLegendDTO();
    }

    //All function from here are for legend  delete
    public void deleteLegendType(LegendDTO dto) {
        LegendDAO dao = new LegendDAO();
        if (dao.deleteLegendType(dto.getLegendName())) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Deleted !"));
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Deleted Error !"));
        }
    }

    //All function from here is to legend edit
    public void editLegendType(LegendDTO dto) {
        edit = true;
        Logger.getLogger(LegendController.class.getName()).warning("DTO : " + dto.legendName);
        legendDTO = dto;
        LegendDAO dao = new LegendDAO();
        Logger.getLogger(LegendController.class.getName()).warning("Edit dto set");
        try {
            List<Legend> legends = dao.getDetailForEditLegend(dto.getLegendName());
            if (legends == null || legends.isEmpty()) {
                dto.getList().add(new Legend());
            } else {
                dto.setList(legends);
            }
        } catch (SQLException ex) {
            Logger.getLogger(LegendController.class.getName()).warning("SQL EXception has occoured");
        }
        Logger.getLogger(LegendController.class.getName()).warning("In Edit Legend Function The size of list" + dto.getList().size());

    }
}

//xhtml代码

       <?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:rich="http://richfaces.org/rich"
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <ui:composition template="/legendTemplate.xhtml">
            <ui:define name="windowTitle">Change Legend</ui:define>
            <ui:define name="content">


                <h:messages globalOnly="true"/>
                <rich:panel id="firstPanel">
                    <h:form id="nis_viewLegend">
                        <rich:dataTable id="data_tbl" value="#{legendbean.legendDTOs}" var="legendDTOvar" style="width:100%" rendered="#{!legendbean.edit and not empty legendbean.legendDTOs}">
                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Description"/>
                                </f:facet>
                                <h:outputText value="#{legendDTOvar.desc}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Legend Type"/>
                                </f:facet>
                                <h:outputText value="#{legendDTOvar.legendName}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Legend Type"/>
                                </f:facet>
                                <h:outputText value="#{legendDTOvar.legendFor}"/>
                            </rich:column>

                            <rich:column>

                                <a4j:commandLink value="Delete" actionListener="#{legendbean.deleteLegendType(legendDTOvar)}" render=":firstPanel"/>
                                <h:outputText value="/"/>
                                <a4j:commandLink value="Edit" actionListener="#{legendbean.editLegendType(legendDTOvar)}" render=":secondPanel :editLegendForm :nis_viewLegend"/>

                            </rich:column>

                        </rich:dataTable>
                    </h:form>
                </rich:panel>

                <rich:panel id="secondPanel">
                    <h:form id="editLegendForm" rendered="#{legendbean.edit}">
                        <h:outputText value="Legend Name"/><br/>
                        <h:inputText value="#{legendbean.legendDTO.legendName}"  readonly="true"/><br/>

                        <h:outputText value="Description"/><br/>
                        <h:inputText value="#{legendbean.legendDTO.desc}"/><br/>

                        <h:outputText value="Legend For"/><br/>
                        <h:inputText value="#{legendbean.legendDTO.legendFor}"/><br/>
                        <br/> 
                        <h:outputText value="Range"  />  
                        <rich:dataTable id="editDataPnl" value="#{legendbean.legendDTO.list}" var="legend" style="width:100%">

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="SN"/>
                                </f:facet>
                                <h:inputText value="#{legend.sn}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Description"/>
                                </f:facet>
                                <h:inputText value="#{legend.desc}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Lower Range"/>
                                </f:facet>
                                <h:inputText value="#{legend.lowerRange}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Upper Range"/>
                                </f:facet>
                                <h:inputText value="#{legend.upperRange}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Color"/>
                                </f:facet>
                                <h:inputText value="#{legend.color}"/>
                            </rich:column>

                            <rich:column>
                                <a4j:commandLink value="Add" actionListener="#{legendbean.addLegendRange}" render=":secondPanel"/>
                                <h:outputText value=" / "/>
                                <a4j:commandLink value="Remove" actionListener="#{legendbean.removeLegendRange(legend)}" render=":secondPanel"/>
                            </rich:column>
                        </rich:dataTable>

                        <br/>
                        <center>
                            <a4j:commandButton value="SAVE" action="#{legendbean.saveLegend()}" render=":firstPanel :secondPanel"/>
                            <a4j:commandButton value="CANCEL" action="#{legendbean.cancel()}" render=":firstPanel :secondPanel"/>
                        </center>
                    </h:form>
                </rich:panel>

            </ui:define>

        </ui:composition>
    </h:body>
</html>

推荐答案

我遇到了同样的问题.我认为上述答案并不能真正解决问题.由于提交任何表单,他没有任何问题-按下这些按钮本身会导致整个页面重新呈现,这意味着在按下按钮之前对视图状态的引用已经消失.这也是我所观察到的.对我来说,它仅在有大量大型搜索结果时发生,并且只需重新提交与我刚刚重新呈现的页面(不执行搜索)相同的搜索即可.我认为问题与限制可以以某种形式传递到服务器的数据量有关:在视图范围内,所有数据都被序列化并以一个长隐藏值作为形式传递给表单.如果该值太长,服务器将不会接受它,因此将不记得以前的状态.

I am having the same problem. I don't think the answers above really address the question. He is not having a problem as a result of submitting any forms - pressing those buttons themselves results in the whole page re-rendering, which means that the reference to the view state is already gone before the button is pressed. This is what I am observing as well. For me, it only happens when there are a lot of large search results, and simply re-submitting the same search I just did re-renders the page (without executing the search). I believe the problem has to do with a limit on the amount of data that can be passed to the server in a form: in view scope, all of the data is serialized and passed around in one long hidden value as a value in the form. If that value is too long the server won't accept it and, therefore, will not remember the previous state.

我知道这不是确定的,但这只是针对我可以找到的这个问题的线索,因此我希望它可以为其他人提供启发或启发更多信息.如果您还有更多确定性的信息,请告诉我们.

I know this is not definitive, but this is only thread out there on this problem I can find so I hope it helps shed light for others or inspires better information. If you have something more definitive please let us know.

我现在确信这是问题所在.我的模型bean引用了文件Blob.一旦我用一个布尔值(只需要知道它是否存在)替换了引用,问题就消失了.尝试传递对DTO/DAO的引用,而不是对象本身,或者在不需要它们持久化的地方将它们标记为瞬态".或者,如果可能的话,照我的方法减轻物体的重量.

I am convinced now that this was the problem. My model bean had a reference to a file blob. Once I replaced that reference with a boolean (only needed to know if it existed) the problem went away. Try passing around references to your DTOs/DAOs instead of the objects themselves, or mark them as "transient" where you don't need them to persist. Or, if possible, lighten the objects as I did.

这篇关于JSF @ViewScoped Bean状态丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆