与会话范围支持 bean 绑定的 JSF 数据表在每次请求时都会一次又一次地呈现

发布于 2024-12-01 15:37:38 字数 6391 浏览 0 评论 0原文

我有一个 XHTML 页面,提交后会返回到自身。
支持 bean 是会话范围的。在重定向到自身时,页面渲染 h:dataable 两次,并给我重复的 id 错误。我可以直观地看到表格被渲染两次,并且彼此相邻。
我发现这与支持bean具有faces html表的属性有关,并且在返回时它再次创建,但是解决方案是什么。

以下内容大致源自此教程 来自 JavaBeat 。唯一的主要区别是我的支持 bean 是会话范围的。

我还意识到我的问题可能还不够清楚,但代码应该:)这里是

支持bean

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.event.ValueChangeEvent;

import com.example.common.web.bean.BaseBean;

@ManagedBean(name = "registrationBean")
@SessionScoped
public class RegisterationViewManagedBean extends BaseBean {


    private String field;
    private List<Employee> employees;
    private Employee employee;
    private HtmlDataTable htmlDataTable;
    private List<Employee> list = new ArrayList();

    public void setSelected(ValueChangeEvent event) {
        employee = (Employee) htmlDataTable.getRowData();
        list = new ArrayList<Employee>();
        list.add(employee);
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    public HtmlDataTable getHtmlDataTable() {
        return htmlDataTable;
    }

    public void setHtmlDataTable(HtmlDataTable htmlDataTable) {
        this.htmlDataTable = htmlDataTable;
    }

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public String dataSubmit() {
        for (Employee employee : this.list) {
            System.out.println(employee.getCity());
            System.out.println(employee.getName());
            System.out.println(employee.getEmpNo());
        }
        return "success";
    }

    public String submit() {
        this.employees = new ArrayList<Employee>();
        Employee employee1 = new Employee();
        employee1.setCity("Bangalore");
        employee1.setEmpNo("1");
        employee1.setName("Krishna");
        Employee employee2 = new Employee();
        employee2.setCity("Bangalore");
        employee2.setEmpNo("2");
        employee2.setName("ShunmugaRaja");
        Employee employee3 = new Employee();
        employee3.setCity("Bangalore");
        employee3.setEmpNo("3");
        employee3.setName("JoyChristy");
        this.employees.add(employee1);
        this.employees.add(employee2);
        this.employees.add(employee3);
        return "success";
    }
}

Xhtml页面

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



    <ui:define name="body">

        <h:form>
            <h:dataTable var="loc" value="#{registrationBean.employees}"
                binding="#{registrationBean.htmlDataTable}">
                <h:column>
                    <h:selectOneRadio onclick="radioButton(this);"
                        valueChangeListener="#{registrationBean.setSelected}">
                        <f:selectItem itemValue="null" />
                    </h:selectOneRadio>
                </h:column>
                <h:column>
                    <h:outputText value="#{loc.name}" />
                </h:column>
                <h:column>
                    <h:outputText value="#{loc.empNo}" />
                </h:column>
                <h:column>
                    <h:outputText value="#{loc.city}" />
                </h:column>
            </h:dataTable>
            <!-- Summary ends -->
            <div class="submitButtons">
                <h:commandButton id="register" action="#{registrationBean.submit}"
                    value="Perform Some Action" />
            </div>
        </h:form>
    </ui:define>
</ui:composition>

堆栈跟踪

Caused by: java.lang.IllegalStateException: component with duplicate id "j_id397249623_10fed7a7:j_id397249623_10fed7bd:j_id397249623_10fed793" found
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.checkIds(DefaultFaceletsStateManagementStrategy.java:784)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.checkIds(DefaultFaceletsStateManagementStrategy.java:800)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.checkIds(DefaultFaceletsStateManagementStrategy.java:800)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.checkIds(DefaultFaceletsStateManagementStrategy.java:800)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.saveView(DefaultFaceletsStateManagementStrategy.java:432)
    at org.apache.myfaces.application.StateManagerImpl.saveView(StateManagerImpl.java:160)
    at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1554)
    at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:281)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:59)
    at org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper.renderView(ResourceViewHandlerWrapper.java:93)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:59)
    at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:85)
    at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:239)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:191)

捕捉 在此处输入图像描述

I have a XHTML page which on submission goes back to itself.
The backing bean is session scoped. On the redirect to itself the page renders the h:dataable twice and gives me duplicate id error.I can visually see the table being rendered twice as well next to each other.
I releaize that it has some thing to do with the fact that backing bean has a property of faces html table and on return it creates again but whats the solution.

Following is roughly derived from this tutorial from JavaBeat . Only main difference is that my backing bean is Session Scoped.

I also releaize that my question probably does not clears it enough but code should :) here it is

Backing bean

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.event.ValueChangeEvent;

import com.example.common.web.bean.BaseBean;

@ManagedBean(name = "registrationBean")
@SessionScoped
public class RegisterationViewManagedBean extends BaseBean {


    private String field;
    private List<Employee> employees;
    private Employee employee;
    private HtmlDataTable htmlDataTable;
    private List<Employee> list = new ArrayList();

    public void setSelected(ValueChangeEvent event) {
        employee = (Employee) htmlDataTable.getRowData();
        list = new ArrayList<Employee>();
        list.add(employee);
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    public HtmlDataTable getHtmlDataTable() {
        return htmlDataTable;
    }

    public void setHtmlDataTable(HtmlDataTable htmlDataTable) {
        this.htmlDataTable = htmlDataTable;
    }

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public String dataSubmit() {
        for (Employee employee : this.list) {
            System.out.println(employee.getCity());
            System.out.println(employee.getName());
            System.out.println(employee.getEmpNo());
        }
        return "success";
    }

    public String submit() {
        this.employees = new ArrayList<Employee>();
        Employee employee1 = new Employee();
        employee1.setCity("Bangalore");
        employee1.setEmpNo("1");
        employee1.setName("Krishna");
        Employee employee2 = new Employee();
        employee2.setCity("Bangalore");
        employee2.setEmpNo("2");
        employee2.setName("ShunmugaRaja");
        Employee employee3 = new Employee();
        employee3.setCity("Bangalore");
        employee3.setEmpNo("3");
        employee3.setName("JoyChristy");
        this.employees.add(employee1);
        this.employees.add(employee2);
        this.employees.add(employee3);
        return "success";
    }
}

Xhtml Page

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



    <ui:define name="body">

        <h:form>
            <h:dataTable var="loc" value="#{registrationBean.employees}"
                binding="#{registrationBean.htmlDataTable}">
                <h:column>
                    <h:selectOneRadio onclick="radioButton(this);"
                        valueChangeListener="#{registrationBean.setSelected}">
                        <f:selectItem itemValue="null" />
                    </h:selectOneRadio>
                </h:column>
                <h:column>
                    <h:outputText value="#{loc.name}" />
                </h:column>
                <h:column>
                    <h:outputText value="#{loc.empNo}" />
                </h:column>
                <h:column>
                    <h:outputText value="#{loc.city}" />
                </h:column>
            </h:dataTable>
            <!-- Summary ends -->
            <div class="submitButtons">
                <h:commandButton id="register" action="#{registrationBean.submit}"
                    value="Perform Some Action" />
            </div>
        </h:form>
    </ui:define>
</ui:composition>

Stack trace

Caused by: java.lang.IllegalStateException: component with duplicate id "j_id397249623_10fed7a7:j_id397249623_10fed7bd:j_id397249623_10fed793" found
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.checkIds(DefaultFaceletsStateManagementStrategy.java:784)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.checkIds(DefaultFaceletsStateManagementStrategy.java:800)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.checkIds(DefaultFaceletsStateManagementStrategy.java:800)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.checkIds(DefaultFaceletsStateManagementStrategy.java:800)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.saveView(DefaultFaceletsStateManagementStrategy.java:432)
    at org.apache.myfaces.application.StateManagerImpl.saveView(StateManagerImpl.java:160)
    at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1554)
    at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:281)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:59)
    at org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper.renderView(ResourceViewHandlerWrapper.java:93)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:59)
    at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:85)
    at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:239)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:191)

Snap
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

堇年纸鸢 2024-12-08 15:37:38

问题是您正在使用会话范围的 bean 来存储页面绑定。第一次按预期呈现页面。第二次,绑定已经有一个组件,因此所有子项都被复制。该问题无法通过更改 JSF 实现来解决(因为两者都具有从 Facelets 继承的相同代码)。尝试使用两个 bean,一个为会话范围,另一个为绑定的请求范围。

The problem is you are using a session scoped bean to store a page binding. The first time the page is rendered as expected. The second time, the binding has already a component, so all children is duplicated. The problem cannot be solved changing of JSF implementation (because both has the same code inherited from facelets). Try use two beans, one session scoped and the other one request scoped with the binding.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文