jsf-2 - 相同 View 的 session 范围 bean

标签 jsf-2 richfaces cdi

我有一个包含列表的 DTO。当用户单击添加按钮时,我想向数据表添加新行。但是当我点击 添加 dto 即构造函数被调用,值被初始化并且列表大小为 0。 bean 是对话范围的。我应该开始和结束使用对话范围 bean 时的相同 View 的对话? 我正在使用相同的 bean 进行编辑,它运行良好。如何在使用 Richfaces 4 和 jsf 2 和 ajax 时解决初始化问题。

查看:

                    <rich:panel id ="dataPnl">
                        <rich:dataTable 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>
                                <a4j:commandLink value="Add" actionListener="#{legendbean.addLegendRange()}" render="nisForm:dataPnl"/>
                                <h:outputText value=" / "/>
                                <a4j:commandLink value="Remove" actionListener="#{legendbean.removeLegendRange(legend)}" render="nisForm:dataPnl"/>
                            </rich:column>

                        </rich:dataTable>
                    </rich:panel>                 

bean :
@Named("legendbean")
@ConversationScoped
public class LegendController implements Serializable {

    LegendDTO legendDTO = new LegendDTO();
    String selectedLegend;
    boolean edit;
    @Inject
    private Conversation conversation;

    public boolean isEdit() {
        return edit;
    }

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

    public LegendController() {
        Logger.getLogger(LegendController.class.getName()).warning("The value of Edit is : " + edit);
        if (!edit) {
            legendDTO.getList().add(new Legend());
            Logger.getLogger(LegendController.class.getName()).warning("The size of list" + legendDTO.getList().size());
        }
    }

    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)) {
            if (edit) {
                conversation.end();
                edit = false;
                Logger.getLogger(LegendController.class.getName()).warning("Save Legend Edit" + edit);
                return "VIEWLEGEND";
            } else {
                legendDTO = new LegendDTO();
                legendDTO.getList().add(new Legend());              
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Saved !"));
                return "";
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Could Not Save Confim if you have already defined Legend " + legendDTO.getLegendName() + "!"));
            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 String editLegendType(LegendDTO dto) {
        conversation.begin();
        edit = true;
        legendDTO = dto;
        LegendDAO dao = new LegendDAO();
        dto.getList().clear();
        try {
            List<Legend> legends = dao.getDetailForEditLegend(dto.getLegendName());
            dto.setList(legends);
        } catch (SQLException ex) {
            Logger.getLogger(LegendController.class.getName()).warning("SQL EXception has occoured");
        }
        Logger.getLogger(LegendController.class.getName()).warning("The size of list" + dto.getList().size());
        return "addLegend";
    }

    public String cancel() {
        conversation.end();
        return "VIEWLEGEND";
    }
}

最佳答案

是的,您需要 start一个长时间运行的对话,以使您的对话(和对话范围的 bean)跨越多个请求。否则 session 在 JSF 请求结束时被终止(默认情况下 session 是暂时的:引用 ConversationScoped javadoc)。

在您这样的情况下,一个常见的解决方案是使用 ViewScoped bean,但注解是 JSF2 特定的,不在 CDI 中显示(您可以将其移植到 CDI 或使用 seam-faces 模块,更多详细信息:http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/)。

关于jsf-2 - 相同 View 的 session 范围 bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12245867/

相关文章:

java - 文件因重音符号而被截断

jakarta-ee - Spring 3.1 和 jBPM 5.2 (+ JSF2/Richfaces4) 集成

jsf - 整个应用程序的单个用户?

java - CDI 1.1 : Is @Observes @Initialized(TransactionScoped. 类)应该可以工作吗?

jsf - 拦截器不适用于 JSF 托管 bean?

jsf - UISelectOne 和 UISelectMany 组件如何在 f :selectItems 中预选默认值

html - <p :media> component 隐藏的 PrimeFaces 菜单栏选项

java - JSF 实用程序类

css - 如何减小 rich :Editor in jsf 的大小

java - CDI:beans.xml,我把你放在哪里?