0

我有一个代码允许老师添加学生并查看他们,但是每次我添加一个学生时,前一个学生也会被覆盖。

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

<h:body>
<h:form>
    <h1><label>Student Grades</label></h1>
    <hr />
    <h:dataTable value="#{course.studentList}" var="st" border="1" rendered="#{course.render}">
        <f:facet name="caption">#{course.courseCode} #{course.courseName}</f:facet>
        <h:column>
            <f:facet name="header">Student Name</f:facet>
            <h:outputText value="#{st.studentName}" />
        </h:column>
        <h:column>
            <f:facet name="header">Score</f:facet>
            <h:outputText value="#{st.studentScore}" />
        </h:column>
    </h:dataTable><br />
    <label>Student Name</label>
    <h:inputText id="studentName" label="Student Name" value="#{student.studentName}" required="true" requiredMessage="Please enter a student name">
    </h:inputText>
    <h:message for="studentName" /><br />
    <label>Student Score</label>
    <h:inputText id="studentScore" label="Student Score" value="#{student.studentScore}" required="true" converterMessage="You must enter a number">
    <f:validateDoubleRange minimum="0" maximum="100" />
    </h:inputText>
    <h:message for="studentScore" /><br />
    <h:commandButton value="Add Grade" action="#{course.add(student)}"/>
    <h:commandButton value="Submit" action="summary"/>
</h:form>
</h:body>
</html>

下面是student.java

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name = "student")
@SessionScoped
public class Student {
private String studentName;
private Double studentScore;

public String getStudentName() {
    return studentName;
}

public void setStudentName(String studentName) {
    this.studentName = studentName;
}

public Double getStudentScore() {
    return studentScore;
}

public void setStudentScore(Double studentScore) {
    this.studentScore = studentScore;
}
}

下面是 Course.java,它有一个学生数组列表。

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import java.util.ArrayList;

@ManagedBean(name = "course")
@SessionScoped
public class Course {
private String courseName;
private String courseCode;
private ArrayList<Student> studentList = new ArrayList<Student>();
private double courseAverage;
private boolean render;

public String getCourseName() {
    return courseName;
}

public void setCourseName(String courseName) {
    this.courseName = courseName;
}

public String getCourseCode() {
    return courseCode;
}

public void setCourseCode(String courseCode) {
    this.courseCode = courseCode;
}

public ArrayList<Student> getStudentList() {
    return studentList;
}

public void setStudentList(ArrayList<Student> studentList) {
    this.studentList = studentList;
}

public double getCourseAverage() {
    int i = 0;
    for (Student st : studentList) {
        courseAverage += st.getStudentScore();
        i++;
    }
    return courseAverage/i;
}

public void setCourseAverage(double average) {
    this.courseAverage = average;
}

public boolean isRender() {
    return render;
}

public void setRender(boolean render) {
    this.render = render;
}

public String add(Student student) {
    studentList.add(student);
    render = true;
    return null;
}

public String reset() {
    studentList = new ArrayList<Student>();
    courseName = "";
    courseCode= "";
    courseAverage = 0.0;
    render = false;
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    return "home";
}

public boolean renderable() {
    boolean render = false;
    for (Student st : studentList) {
        render = true;
    }
    return render;
}
}
4

2 回答 2

0

由于您的Student类被注释为@SessionScoped @ManagedBean,它将在整个用户的 HTTP 会话中创建和存储,即除非它无效或过期。因此,当您向列表添加一个值时,您基本上在任何地方都添加了一个非常相同的引用,您所做的只是修改Student曾经创建的对象的字段,然后它的字段被不断替换,因此,每个列表元素都包含一个对同一 Student对象的引用也进行了修改。

Student您需要做的是创建一个要添加到列表中的全新对象,并为此从其中删除任何 bean 注释。

附带说明一下,在继续进行之前,请务必了解托管 bean 和模型/占位符之间的区别和用例。

于 2013-04-18T16:33:28.607 回答
0

Course.add方法中添加参数的副本student

原因:即使是请求范围的 bean 也可能被容器重复/重用。在任何情况下,它都更具防御性。

于 2013-04-18T16:42:53.090 回答