如何在使用@viewScoped Beans将搜索页面导航到JSF 2中的编辑页面时,在编辑页面中填充数据?

时间:2014-01-21 14:01:38

标签: jsf jsf-2

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

另请注明以下内容。

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)

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

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

1 个答案:

答案 0 :(得分:2)

  

执行请求生命周期过程时@viewScoped bean的范围是什么。 @viewScoped bean是否已进入请求范围?

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


  

JSF中的Flash范围是什么。

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


  

我是否需要在上述场景中使用Flash范围来填充编辑页面中的数据?

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