我有一个代码,允许教师添加学生并查看它们,但每次我添加学生时,前一个学生也会被覆盖。
<!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,其中有一个学生的arraylist。
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;
}
}
答案 0 :(得分:0)
当您的Student
类注释为@SessionScoped
@ManagedBean
时,它将在整个用户的HTTP会话中创建和存储,即除非它失效或过期。因此,当您向列表中添加一个值时,您基本上会在任何地方添加一个相同的引用,而您所做的只是修改曾经创建的Student
对象的字段,之后它的字段会不断被替换,因此,< em>包含对相同 Student
对象的引用的每个列表元素也被修改。
您需要做的是创建一个全新的Student
对象,该对象将添加到列表中,并基本上从中删除任何bean注释。
作为旁注,请务必先了解托管bean与模型/占位符之间的区别和用例,然后再继续。
答案 1 :(得分:0)
在Course.add
方法中添加参数student
的副本。
原因:即使是请求范围的bean也可能被容器重复/重用。在任何情况下,它都更具防御性。