2

I have 2 classes - Student and Course. Both have all getters and setters defined on the attributes inside them. Using these two classes I am trying to build a web application with general functions like editing and adding students in different jsp pages. I student could have enrolled in multiple courses and marks for each course of each student should be editable inside the app.

Now i have a studentMarks.jsp which loads the data from an action class - StudentAction

public class StudentAction extends ActionSupport {
    private static final long serialVersionUID = 1L;
    private List<Student> studentList;
    private List<Course> courseList;
    private HashMap<Student,List<Course>> studentCourseList; 
    private int rollNo;
    private String name;
    private String DOB;
    StudentService studentService;
    CourseService courseService;
    Student student;
    Course course;    
    /**** Setters and getters for all the attributes here **/

    public String studentCourseList() {
        this.studentList = studentService.getStudentRecords();          
        studentCourseList = new HashMap<Student, List<Course>>();
        for(Student s : studentList) {              
            this.studentCourseList.put(s,courseService.getStudentCourses(s.getRollNo()));
        }
        return "SUCCESS";
    }

    public String editCoursePage() {
        this.student = studentService.getStudent(rollNo);
        this.courseList = courseService.getStudentCourses(rollNo);
        return "SUCCESS"; //loads the editCourse.jsp
    }

    public String editCourseAction() {
        System.out.print("This line displays null pointer exception" + courseList.size());
        //courseService.editCourse(rollNo,this.courseList);
        return "SUCCESS";
    }
}

First a page is loaded that executes studentCourseList action which populates the page with all records(this page works fine) and after every record there is an edit button. Upon clicking edit, editCoursePage is called which set one student object and gets a list of courses for this student. Please note that i am not reusing the course list from the hashmap. In this page the student marks are displayed with the marks inside the textboxes to allow for editing. This page is displaying proper student information.

editCourse.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                      "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Edit courses</title>
    </head>
    <body>

        Student: <s:label value="%{student.name}" />

        <s:form action="editCourseAction">
            <s:hidden name="rollNo" value="%{student.rollNo}" />

            Courses: 

            <s:iterator value="courseList" var="courses">
                <s:label ><s:property value="name" /></s:label>
                <s:textfield name="marks" theme="simple"/>
                <br />            
            </s:iterator>

            <s:submit action="editCourseAction" value="submit" />

        </s:form>
    </body>
</html>

Course.java

@Entity
@Table(name="courses")
public class Course {

    @Id
    @GeneratedValue
    @Column(name="id")
    int id;

    @Column(name="marks")
    int marks;

    @Column(name="rollNo")
    int rollNo;

    @Column(name="course")
    String course;
    //all getters and setters
}

Now this form is displaying correct data but the problem is that upon submitting, it does not pass the values of courses back to editCourseAction. I have already tried all sort of OGNL expressions that can populate a list through form but cannot get it done. It always through NPE if i try to get the value of courseList in action class. Although it doesn send the rollNo correctly. Please tell me what am i doing wrong. Is it the syntax problem or is the approach that is wrong ?

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
ishan
  • 1,202
  • 5
  • 24
  • 44

1 Answers1

4

If you want to send back to Action a list of objects you need to specify an index in the name attribute:

instead of

<s:iterator value="courseList">
   <s:textfield name="marks" />
</s:iterator>

use

<s:iterator value="courseList" status="ctr">
   <s:textfield name="courseList[%{#ctr.index}].marks" />
</s:iterator>
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • When or how does the Struts2 framework create the list when the form is submitted back to the action class? I'm stuck on a similar problem and understanding this might be the key (my list is `null` when I reach the action upon submitting the form, but I can verify the post request sends the list's values like `myList[index].attribute`) – JorgeGRC Sep 09 '15 at 10:20
  • You are probably not passing through the parameters interceptor... Check it out – Andrea Ligios Sep 09 '15 at 14:20
  • I'm embarrassed, but the problem was I didn't write down the setter method for the List.. now I'm facing a very different problem, the form seems to be submited more than once (I think) and thus the framework tries to set a `String[]` on my list object's attributes (as there would be more than 1 parameter with the same name)... I'll try to work this out but I might post a new question instead of hijacking this one :) – JorgeGRC Sep 09 '15 at 15:28
  • 1
    Nevermind, I found the issue... it was related to my design and had nothing to do with `struts2` – JorgeGRC Sep 09 '15 at 15:36