【问题标题】:How to populate data in Edit page when navigated form Seach page to Edit page in JSF2 with @viewScoped Beans?使用@viewScoped Beans 将表单搜索页面导航到JSF 2 中的编辑页面时,如何在编辑页面中填充数据?
【发布时间】:2014-01-21 14:01:38
【问题描述】:

您好,从搜索页面导航到编辑页面时,我在编辑页面中填充数据时遇到问题。我可以在employeeBean.edit 方法中看到employeeDTO 数据,但在编辑页面渲染完成时不可用。请帮我找出问题。

还请澄清以下内容。

1) 请求生命周期过程执行时@viewScoped bean 的作用域是什么。 @viewScoped bean 是否放入请求范围?

2) JSF 中的 Flash 作用域是什么。我是否需要在上述场景中使用 flash 范围在编辑页面中填充数据?

下面是代码。

EmployeeCreate.xhtml(用于创建和更新操作)

<!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:f="http://java.sun.com/jsf/core"
        xmlns:ui="http://java.sun.com/jsf/facelets">

    <h:head><title>Employee Registration</title>
    <link href="../css/styles.css" 
          rel="stylesheet" type="text/css"/> 
    </h:head>
    <h:body>
    <div align="center">

    <h:form>
    <h:panelGrid columns="3" styleClass="formTable">
      Employee Name: 
      <h:inputText value="#{employeeBean.employeeDTO.empName}" 
                   required="true"
                   id="empName">
      </h:inputText>
      <h:message for="empName" styleClass="error"/>

      Employee Location: 
      <h:inputText value="#{employeeBean.employeeDTO.empLocation}" 
                   required="true" 
                   id="empLocation">
      </h:inputText>
      <h:message for="empLocation" styleClass="error"/>

    </h:panelGrid>
      <h:commandButton value="Submit" 
                       action="#{employeeBean.submit}"/>
    </h:form>
    </div>
    </h:body>
    </html>

EmployeeSearch.xhtml

<!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:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head><title>Employee Search Result</title>
<link href="../css/styles.css" 
      rel="stylesheet" type="text/css"/> 
</h:head>
<h:body>
<div align="center">

<h:form>

    <h1>Employee List</h1>

            <h:dataTable value="#{employeeSearchBean.employeesList}" var="emp">
                <h:column>
                    <!-- column header -->
                    <f:facet name="header">Employee ID</f:facet>
                    <!-- row record -->
                    <h:commandLink value="#{emp.empId}" action="#{employeeBean.edit}">
                        <f:setPropertyActionListener target="#{employeeBean.employeeDTO}" value="#{emp}" />
                    </h:commandLink>
                </h:column>

                <h:column>
                    <f:facet name="header">Employee Name</f:facet>
                    #{emp.empName}
                </h:column>

                <h:column>
                    <f:facet name="header">Employee Location</f:facet>
                    #{emp.empLocation}
                </h:column>

            </h:dataTable>


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

EmployeeBean.java(用于创建/更新操作等)

package com.employee;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class EmployeeBean {

    private EmployeeDTO employeeDTO;

    @PostConstruct
    public void init(){
        System.out.println(">>>>>>> init >>>>");
    }


    public EmployeeDTO getEmployeeDTO() {
        return employeeDTO;
    }

    public void setEmployeeDTO(EmployeeDTO employeeDTO) {
        this.employeeDTO = employeeDTO;
    }

    public String edit(){
        System.out.println(">>> edit employee Id >>> " + employeeDTO.getEmpId() );
        return "edit";
    }

    public String submit(){
        // to do
        return null;
    }

}

EmployeeSearchBean.java(我的项目需要单独的bean进行Search操作)

@ManagedBean
@ViewScoped
public class EmployeeSearchBean {

    List<EmployeeDTO> employeesList;

    public List<EmployeeDTO> getEmployeesList(){
        employeesList = new ArrayList<EmployeeDTO>();

        EmployeeDTO  emp1 = new EmployeeDTO();
        emp1.setEmpId(new Long(1));
        emp1.setEmpLocation("Location1");
        emp1.setEmpName("Mike");

        EmployeeDTO  emp2 = new EmployeeDTO();
        emp2.setEmpId(new Long(2));
        emp2.setEmpLocation("Location2");
        emp2.setEmpName("name2");

        EmployeeDTO  emp3 = new EmployeeDTO();
        emp3.setEmpId(new Long(3));
        emp3.setEmpLocation("Location3");
        emp3.setEmpName("name3");

        employeesList.add(emp1);
        employeesList.add(emp2);
        employeesList.add(emp3);

        return employeesList;

    }
}

EmployeeDTO.java

public class EmployeeDTO implements Serializable {

    private static final long serialVersionUID = 1L;


    private Long empId; 

    private String empName;

    private String empLocation;
    // setters and getters ........
}

faces-config.xml

<managed-bean>
        <managed-bean-name>employeeBean</managed-bean-name>
        <managed-bean-class>com.employee.EmployeeBean</managed-bean-class>
        <managed-bean-scope>view</managed-bean-scope>
          <managed-property>
            <property-name>employeeDTO</property-name>
            <value>#{employeeDTO}</value>
          </managed-property>
    </managed-bean>

    <managed-bean>
        <managed-bean-name>employeeDTO</managed-bean-name>
        <managed-bean-class>com.employee.EmployeeDTO</managed-bean-class>
        <managed-bean-scope>view</managed-bean-scope>
    </managed-bean>

    <navigation-rule>
        <from-view-id>/jsf/EmployeeSearch.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>edit</from-outcome>
            <to-view-id>/jsf/EmployeeCreate.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>

提前致谢。任何帮助表示赞赏。

【问题讨论】:

    标签: jsf jsf-2


    【解决方案1】:

    在执行请求生命周期过程时,@viewScoped bean 的作用域是什么。 @viewScoped bean 是否放入请求范围?

    不。它们被放入视图范围。只有@RequestScoped bean 被放入请求范围。视图范围与 JSF 视图具有相同的生命周期,而不是 HTTP 请求。另见How to choose the right bean scope?


    JSF 中的 Flash 作用域是什么。

    flash 作用域的寿命与单个重定向一样长。因此,如果您将重定向从页面 A 发送到页面 B,并在重定向之前将某些内容放入页面 A 中的 flash 范围内,那么它仅且仅在重定向到页面 B 的请求中可用,而在任何其他请求中均不可用。但是,flash 范围不是 JSF 托管的 bean 范围。闪存范围由映射表示,支持 bean 中的 ExternalContext#getFlash() 和 EL 中的 #{flash} 可用。


    是否需要在上述场景中使用 flash scope 来填充编辑页面中的数据?

    这是一种方式,是的。但是,您没有发送重定向。您只是在同一请求中返回不同的视图(因此隐式创建了不同的视图范围)。您最好通过请求范围传递数据。通过ExternalContext#getRequestMap(),或者通过普通的 GET 链接而不是 POST 表单更好。另请参阅此处的主从示例:Creating master-detail pages for entities, how to link them and which bean scope to choose

    【讨论】:

    • 您能否解释一下在执行渲染响应阶段时从何处检索到的employeeBean.employeeDTO 数据以显示在编辑页面中。在我的情况下,正如你上面解释的那样,当我从搜索页面导航到编辑页面时,搜索页面视图中可用的employeeBean 在编辑页面视图中将不可用(原因是新的编辑页面视图,新视图地图是创建),是否正确?
    • 点击答案底部的链接,将“产品”替换为“员工”。
    • 感谢@BalusC,通过使用带有
    • 我不知道你在问什么。
    • 嗨,@BalusC,在 EmployeeCreate.xhtml(用于创建和更新操作)中,我提到了 将请求参数值设置为 employeeBean.employeeDTO 属性。当这些请求参数值设置为employeeBean.employeeDTO 属性时,是否会从为新视图创建的viewMap(即EmployeeCreate.xhtml)中引用employeeBean?另外,请就您在答案中提到的如何使用 Flash 实现上述场景提出您的建议。
    猜你喜欢
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多