Issue
I'm fairly new to using Servlets and JSP and I'm trying to get a JSP page which lists all users, to redirect to an edit form jsp depending on user id, the JSP page which list all users uses an iterator to display data from my JDBC table but i cant seem to figure out how to individually assign a value to the edit link of each user so it can load the edit form with the data of that user, your help would be appreciated.
here my current code for jsp page to list all students
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" import="java.util.*" import="model.Student"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, intial-scale=1 shink-to-fit=yes">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-..." crossorigin="anonymous">
</head>
<body>
<nav class="navbar navbar-dark bg-primary pd-8">
<a class="navbar-brand"> ...University</a>
</nav>
<div class="container-fluid">
<div class="container">
<div class="form container-fluid p-4">
<a href="<%=request.getContextPath()%>/new" class="btn btn-success" >Add
Student</a>
</div>
<br>
<!--Assigning ArrayList object containing student data to the local object -->
<% ArrayList<Student> studentList = (ArrayList) request.getAttribute("listStudents"); %>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<!-- data from table displayed using iterator-->
<%
if(request.getAttribute("listStudents") != null) {
Iterator<Student> iterator = studentList.iterator();
while(iterator.hasNext()) {
Student studentDetails = iterator.next();
%>
<tr><td><%=studentDetails.getId()%></td>
<td><%=studentDetails.getName()%></td>
<td><%=studentDetails.getEmail()%></td>
<td><a href="<%=request.getContextPath()%>/edit?id=<%=studentDetails.getId()%>">Update</a> <!-- id assigned to edit link-->
<a href="<%=request.getContextPath()%>/delete?id=<%=studentDetails.getId()%>">Delete</a></td> <!-- id assigned to delete link-->
</tr>
<%
}
}
%>
</tbody>
</table>
</div>
</div>
</body>
</html>
the id value is then supposed to be assigned to a value in the servlet which is used to select the specific student from the table when edit is called
here is part of my servlet code:
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import dao.StudentDao;
import model.Student;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class StudentServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private StudentDao studentDao;
public StudentServlet() {
this.studentDao = new StudentDao();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String sPath = request.getServletPath();
//switch statement to call appropriate method
switch (sPath) {
case "/new":
try {
showNewForm(request, response);
} catch (ServletException | IOException e) {
e.printStackTrace();
}
break;
case "/insert":
try {
insertStudent(request, response);
} catch (SQLException | IOException e) {
e.printStackTrace();
}
break;
case "/delete":
try {
deleteStudent(request, response);
} catch (SQLException | IOException e) {
e.printStackTrace();
}
break;
case "/update":
try {
updateStudent(request, response);
} catch (SQLException | IOException e) {
e.printStackTrace();
}
break;
case "/edit":
try {
editStudent(request, response);
} catch (ServletException | IOException e) {
e.printStackTrace();
}
break;
default:
try {
listAllStudents(request, response); //home page = .../week04/StudentServlet
} catch (ServletException | IOException | SQLException e) {
e.printStackTrace();
}
break;
}
}
private void editStudent(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int id = Integer.parseInt(request.getParameter("id"));
Student currentStudent = studentDao.selectStudent(id);
System.out.println(currentStudent);
RequestDispatcher dispatch = request.getRequestDispatcher("student-form.jsp");
request.setAttribute("student", currentStudent);
dispatch.forward(request, response);
}
private void listAllStudents(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, SQLException {
List<Student> allStudents = studentDao.selectAllStudents();
request.setAttribute("listStudents", allStudents);
RequestDispatcher dispatch = request.getRequestDispatcher("student-list.jsp");
dispatch.forward(request, response);
}
}
here is my DAO in case i didnt configure it properly:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import model.Student;
public class StudentDao {
private String jdbcURL = "jdbc:mysql://localhost:3308/xyzuniversity";
private String jdbcUsername = "User";
private String jdbcPassword = "password";
private static final String SELECT_STUDENT_ID = "SELECT name, email FROM student WHERE id =?";
protected Connection getConnection() {
Connection connection = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);
}catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
return connection;
}
public Student selectStudent(int id) {
Student student = null;
try {
Connection connection = getConnection();
PreparedStatement prepStatement = connection.prepareStatement(SELECT_STUDENT_ID);
prepStatement.setInt(1, id);
ResultSet rSet = prepStatement.executeQuery();
while(rSet.next()) {
String name = rSet.getString("name");
String email = rSet.getString("email");
student = new Student(id, name, email);
}
} catch (SQLException e) {
e.printStackTrace();
}
return student;
}
And finally the jsp form that should be displayed
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, intial-scale=1 shink-to-fit=yes">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384..." crossorigin="anonymous">
</head>
<body>
<nav class="navbar navbar-dark bg-primary pd-8">
<a class="navbar-brand"> XYZ University</a>
</nav>
<div class="container col-md-5 p-4">
<div class="card">
<div class="card-body">
<% if (request.getAttribute("student") != null) { %>
<!-- form display depends on whether there is data in the table -->
<form action="<%=request.getContextPath()%>/update" method="post">
<% } else { %>
<form action="<%=request.getContextPath()%>/insert" method="post">
<% } %>
<div>
<h2>
<% if (request.getAttribute("student") != null) { %>
Edit Student
<% } else { %>
Add New Student
<% } %>
</h2>
</div>
<% if (request.getAttribute("student") != null) { %>
<input type="hidden" name="id" value="<%=request.getAttribute("student.id") %>" />
<% } %>
<fieldset class="form-group">
<legend>Name</legend>
<% if (request.getAttribute("student") != null) { %>
<input type="text" value="<%=request.getAttribute("student.name") %>" class="form-control" name="name" required="required">
<% } else { %>
<input type="text" value="" class="form-control" name="name" required="required">
<% } %>
</fieldset>
<fieldset class="form-group">
<legend>Email</legend>
<% if (request.getAttribute("student") != null) { %>
<input type="text" value="<%=request.getAttribute("student.email") %>" class="form-control" name="email">
<% } else { %>
<input type="text" value="" class="form-control" name="email">
<% } %>
</fieldset>
<button type="submit" class="t-3 btn btn-success">Save</button>
</form>
</div>
</div>
</div>
</body>
</html>
i assumed i got the id value by setting the edit url to href="<%=request.getContextPath()%>/edit?id=<%=studentDetails.getId()%>" but the form opens with a null value which i can't figure where I'm going wrong or how now to assign the value
truly don't know what to do now and I've tried searching for solutions but none seem to help with my problem any help would be appreciated.
Solution
The issue is that your request
attribute's name is student
request.setAttribute("student", currentStudent);
but your attribute lookup code is looking for student.id
which then returns null
.
<input type="hidden" name="id" value="<%=request.getAttribute("student.id") %>" />
So, you need to get the attribute first and then its properties to populate your form <input>
s as
<input type="hidden" name="id" value="<%= ((Student) request.getAttribute("student")).getId() %>" />
<input type="text" name="name" value="<%= ((Student) request.getAttribute("student")).getName() %>" ... />
<input type="text" name="email" value="<%= ((Student) request.getAttribute("student")).getEmail() %>" ... />
request.getAttribute()
method's return type is an Object
, so, a cast to Student
is required before accessing the properties with getters. This means the JSP page would need an import
directive too.
<%@ page import="model.Student" %>
But, I would recommend using the JSP EL expression language syntax to shorten these lookups to
<input type="hidden" name="id" value="${student.id}" />
<input type="text" name="name" value="${student.name}" class="form-control" required="required" />
<input type="text" name="email" value="${student.email}" class="form-control" />
This looks much cleaner, is more readable, no need for type casting and handles the null
values gracefully. You don't even need all those null
checks as the value
will automatically be set to ""
if student
attribute is null
.
So, all your form-group
s
<fieldset class="form-group">
<legend>First Name</legend>
<% if (request.getAttribute("student") != null) { %>
<input type="text" value="${student.firstname}" class="form-control"
name="firstname" required="required">
<% } else { %>
<input type="text" value="" class="form-control" name="firstname" required="required">
<% } %>
</fieldset>
can be simplified to just a few lines using EL.
<fieldset class="form-group">
<legend>First Name</legend>
<input type="text" value="${student.firstname}" class="form-control"
name="fistname" required="required">
</fieldset>
Answered By - Ravi K Thapliyal