JSF @ViewScoped Bean 状态丢失

2024-04-16

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

          //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>

例如,在 ViewScope 中,一旦构建了视图form.xhtml,只要您不离开此视图,其数据就会持续存在。要保持在同一视图中,您应该调用具有返回类型的方法void(通常用于actionListener属性)或返回 null,以防返回导航结果。

  • 方法表达式

在您的情况下,您的方法是无效的,但您不是将其传递给操作侦听器,而是在视图中调用它。

尝试更改类似的代码,如下所示:

<a4j:commandButton value="SAVE" actionListener="#{legendbean.saveLegend()}" render="mainPnl"/>

To this:

<a4j:commandButton value="SAVE" actionListener="#{legendbean.saveLegend}" render="mainPnl"/>

As actionListener属性已经需要一个方法表达式。

  • 数据表内的表格

我还注意到你的数据表中有一个表单。这可能会导致奇怪的行为,因为你的表单有一个id它将在结果页面中重复。为此,您应该尝试将表单放置在数据表之外。

更好的是,您可以只有一个包含整个代码的表单,因为嵌套表单是无效的 HTML 代码。

我建议你检查一下你的legendTemplate.xhtml也反对嵌套形式。

  • Bean 构建

为了初始化你的bean状态,建议使用@PostContruct方法而不是 bean 构造函数。

尝试从此改变:

        public LegendController() {
            legendDTO = new LegendDTO();
            legendDTO.getList().add(new Legend());
        }

To this:

        @PostConstruct
        public void reset() {
            legendDTO = new LegendDTO();
            legendDTO.getList().add(new Legend());
        }

并删除你的构造函数。

只要您处于同一视图(也称为 .xhtml 页面),您的 bean 数据就应该保留。

我希望它有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JSF @ViewScoped Bean 状态丢失 的相关文章

随机推荐

  • 浮动操作按钮不显示矢量资源

    I m trying to setup a vector asset into a fab But the result is like this As you can see the vector is there but way dow
  • 有没有办法在Oracle表的指定位置添加列? [复制]

    这个问题在这里已经有答案了 考虑一下我在 Oracle 10G 中创建的初始表 CUSTOMER ID ACC NO ACC BALANCE 100 200 1000 101 150 4000 102 350 2000 103 450 25
  • FFmpeg - 找不到 ExecuteBinaryResponseHandler - Android/Java

    我正在尝试制作一个用于反应原生的模块 它将把视频变成 gif 我对 android studios java 几乎没有经验 但我很想了解更多 我在用这个图书馆 https github com WritingMinds ffmpeg and
  • React Native 箭头函数和“if”语句

    我刚刚接受了箭头函数的教育 以及当您开始使用子函数时它们如何帮助提高可见性React Native 和全局可访问的对象 https stackoverflow com questions 50209526 react native and
  • gdb:“未加载符号表”

    尝试在 gdb 中添加断点时 我不断收到此错误消息 我使用这些命令来编译 gcc g main c utmpib2 c o main o and cc g main c utmpib2 c o main o and also g g mai
  • 升级到 RN 0.68 后 APK 中缺少 index.android.bundle

    将我们的 RN 应用程序升级到 RN 0 68 后 我们在发布版本中遇到错误 FATAL EXCEPTION create react context Process com app PID 15057 java lang RuntimeE
  • 应用程序的私有文件

    我想创建一个文件来存储一些只能由我的应用程序访问的数据 外部用户不应该能够访问该文件或对其进行任何更改 我将在文件中存储一个密钥 该密钥可能由我的应用程序访问需要时随时使用应用程序 使用Environment getDataDirector
  • Meteor如何调用Meteor.methods()中定义的方法?

    我将方法分配给 Meteor 服务器 如下所示 在 bootstrap js 中 Meteor startup function Meteor methods foo function return 1 bar function QUEST
  • Direct2D 位图画笔拉长

    我必须在屏幕外位图上绘制形状 但是当我尝试渲染位图时遇到一个奇怪的问题 这就是图像的显示方式 这就是我查看位图的方式 以下是我用来创建位图画笔的代码 const auto size renderTarget gt GetSize const
  • 内容更改时停止文本小部件滚动

    我有一个带有滚动条的文本小部件 看起来像这样 self myWidget Text root self myWidget configure state DISABLED self myWidget pack self myWidgetSc
  • 在线性回归中使用数据框的列名称作为预测变量

    我正在尝试遍历 data frame 的所有列名称并使用它们 作为线性回归中的预测变量 我目前拥有的是 for i in 1 11 for j in 1 11 if i j var1 names newData i var2 names n
  • 奇怪的错误 TypeError:无法在 onSuccessMapUnitFields 处读取 null 的属性“setValue”[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 这段代码运行得很好 直到我决定再添加 4 行代码 所以我删除了它们 但我收到了这个错误 有趣的是我在Form onloa
  • 防止在弹出窗口外部单击时关闭 SweetAlert

    我在用甜蜜警报电子商务应用程序中我的产品视图上的弹出窗口有两个按钮 一个用于进入购物车视图 另一个用于重新加载视图 但是 当用户在弹出窗口外部单击时 弹出窗口会自动关闭 我已尝试以下属性来阻止其关闭 但没有任何作用 hideOnOverla
  • 将多个模型和自定义字段添加到 Django Rest Framework 中的 json 响应

    我是 Python Django 编程新手 在我正在做的个人项目中遇到了一些问题 我的问题是 我想根据应用程序的不同模型返回自定义响应 一些值将来自自定义查询 其他值是模型本身的一部分 因此 我的应用程序中有以下模型 删除了一些字段以免帖子
  • CodeIgniter 中的超级对象是什么?

    我在 超级对象 中看到了 超级对象 这个词代码点火器手册 http codeigniter com user guide general creating libraries html 但该术语没有详细解释 那么 CodeIgniter 中
  • 在c中动态增加数组(int *)的大小

    我想动态地将数字添加到c中的数组中 我的想法是分配一个大小 1 的新数组 添加数字 释放根数组并将指针从 temp 更改为根数组 像这样 void addNumber int a int size int number size size
  • Django 根据日期时间按日期进行分组计数

    我正在尝试计算用户从日期时间字段注册的日期 在数据库中 它存储为 2016 10 31 20 49 38 但我只对日期 2016 10 31 感兴趣 原始 SQL 查询是 select DATE registered at register
  • Javascript Gallery 自动使用页面上的所有大图像

    我有一个网站 一个大页面上有很多图像 最简单的是我可以包含一个脚本 它自动搜索同一页面并使用所有大于 100 像素的图像来创建幻灯片库 有人知道这样一个简单的脚本 不需要任何编程技能吗 我发现这是一个开始 jQuery 获取大于特定尺寸的元
  • 创建以字母数字开头的 Oracle 序列

    我想创建以字符开头的序列inv并增加 1 的价值观 INV01 INV02 INV03 etc CREATE SEQUENCE invoice nun START WITH INV INCREMENT BY 1 只能创建整数值序列 所以声明
  • JSF @ViewScoped Bean 状态丢失

    我正在将 ViewScoped Bean 用于小型 CRUD 应用程序 我有一个编辑和查看页面 但是当我单击按钮 编辑 时 它将呈现编辑表单 编辑表单出现后 保存按钮或取消按钮不会调用该函数 而是呈现整个页面 actionListener