I am practicing Java-based web development using Tomcat as the application server and following MVC pattern without any framework. I want to send a few fields from the database and display it in a JSP form. For this, I am creating an array list of the data in a java class and then sending it to a controller, which then sends it to the JSP file where it will be shown in a table.
However, the array list is fine in the controller (used .size() method on the ArrayList to confirm equal no. of database records), but the data is apparently null when reaching the JSP page. I have tried going through many links, but most do not apply to my situation (not maven) and the only one that does do not provide a solution. Appreciating any help!
menu_model.java
package Created;
public class menu_model {
private String menuid;
private String menuscr;
private String menuprnt;
public void setmid(String menuid) {
this.menuid = menuid;
}
public void setmscr(String menuscr) {
this.menuscr = menuscr;
}
public void setmprnt(String menuprnt) {
this.menuprnt = menuprnt;
}
public String getmid() {
return menuid;
}
public String getmscr() {
return menuscr;
}
public String getmprnt() {
return menuprnt;
}
}
menu_DAO.java
package Created;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class menu_DAO {
public static String cond = "jdbc:oracle:thin:@localhost:1535:DATABASE";
public static String usnm = "username";
public static String pwrd = "password";
public static ArrayList<menu_model> menu_rtrv(){
try {
PreparedStatement pst = null;
menu_model po;
Class.forName("oracle.jdbc.OracleDriver");
Connection conn = DriverManager.getConnection(cond,usnm,pwrd);
pst = conn.prepareStatement("select m_id,m_scrnm,m_prnt from menu_menus where m_id in "
"(select um_id from um_menus where user_id=? and umenu_enable=?)");
pst.setString(1,"TEST");
pst.setString(2, "YES");
ResultSet rs=pst.executeQuery();
ArrayList<menu_model> rsarr = new ArrayList<>();
while (rs.next())
{
po = new menu_model();
po.setmid(rs.getString("m_id"));
po.setmscr(rs.getString("m_scrnm"));
po.setmprnt(rs.getString("m_prnt"));
rsarr.add(po);
}
conn.close();
return rsarr;
}
catch (ClassNotFoundException | SQLException e)
{
e.getMessage();
}
return null;
}
}
menu_cntrlr.java (Controller)
package Created;
import jakarta.servlet.RequestDispatcher;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.util.ArrayList;
@WebServlet (name = "menu_cntrlr", urlPatterns = {"/mctrl"})
public class menu_cntrlr extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ArrayList alist = menu_items.menu_rtrv();
request.setAttribute("list", alist);
RequestDispatcher dispatcher = request.getRequestDispatcher("m_menu.jsp");
dispatcher.forward(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
m_menu.jsp
<%@page import="java.util.*,Created.menu_model"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="static/vendor/fontawesome/all.min.css" />
<link rel="stylesheet" href="bs_ovrd.css" />
<title>Main menu</title>
</head>
<body>
<table border=2>
<tr>
<th>Menu ID</th>
<th>Menu Scr Name</th>
<th>Menu Parent</th>
</tr>
<%
ArrayList<menu_model> dlist=(ArrayList)request.getAttribute("list");
Iterator it=dlist.iterator();
while(it.hasNext())
{
menu_model m=(menu_model)it.next();
%>
<tr>
<td><%=m.getmid() %></td>
<td><%=m.getmscr() %></td>
<td><%=m.getmprnt() %></td>
</tr>
<%
}
%>
</table>
</body>
</html>
HTTP Status 500 – Internal Server Error (upon loading http://localhost:8080/WebApplication1/m_menu.jsp)
Type Exception Report
Message An exception occurred processing [/m_menu.jsp] at line [30]
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.apache.jasper.JasperException: An exception occurred processing [/m_menu.jsp] at line [30]
28:
29:
30: Iterator it=dlist.iterator();
31: while(it.hasNext())
32: {
33: menu_model m=(menu_model)it.next();
Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:610)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:499)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:380)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:328)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:792)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
java.lang.NullPointerException: Cannot invoke "java.util.ArrayList.iterator()" because "dlist" is null
org.apache.jsp.m_005fmenu_jsp._jspService(m_005fmenu_jsp.java:148)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:792)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:466)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:380)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:328)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:792)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note The full stack trace of the root cause is available in the server logs.
Tried using JSTL and the JSP page loads but the if condition returns and no list:
<c:if test="${empty list}">
it is null
</c:if>
<c:forEach var="mitem" items="${list}">
<td><c:out value="${mitem.menuid}"/></td>
<td><c:out value="${mitem.menuscr}"/></td>
<td><c:out value="${mitem.menuprnt}"/></td>
</c:forEach>
EDIT: I tried passing an integer declared in the controller to the JSP, and found the following error which I think is linked to the previous one:
Exception Report
Message An exception occurred processing [m_menu.jsp] at line [21]
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.apache.jasper.JasperException: An exception occurred processing [m_menu.jsp] at line [21]
18: </head>
19: <body>
20: <%//ArrayList<menu_model> dlist=(ArrayList)request.getAttribute("list");
21: int sc = (int) request.getAttribute("list");
22: out.print(sc);%>
23: <table border=2>
24: <tr>
Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:610)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:499)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:380)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:328)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:792)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "jakarta.servlet.http.HttpServletRequest.getAttribute(String)" is null
org.apache.jsp.m_005fmenu_jsp._jspService(m_005fmenu_jsp.java:145)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:792)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:466)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:380)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:328)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:792)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
The below is the code that I had added:
//in the Controller
int c=2;
request.setAttribute("list", c);
//in the JSP
<% int sc = (int) request.getAttribute("list");
out.print(sc);
%>
CodePudding user response:
When loading the URL http://localhost:8080/WebApplication1/m_menu.jsp, this invokes the JSP directly, without first going through the menu_cntrlr
servlet. This means it never has the opportunity to add attributes to the request. Then, when the JSP tries to access these attributes, they are returned as null
.
In order to invoke the servlet, you need to visit the URL corresponding to the urlPatterns
parameter of its @WebServlet
mapping: http://localhost:8080/WebApplication1/mctrl
This results in the servlet being invoked first, setting the request attribute, and then forwarding to the JSP, which will then be able to read the attribute successfully.
When following the MVC pattern with the Java Servlet API, JSPs should never be accessed directly by URL. They are considered an implementation detail of the controller, and to satisfy their preconditions, the controller must always be invoked first. For that reason it is common to put JSP files into the WEB-INF
directory of the webapp, as this prevents them from being directly addressable by URL from a web browser or other HTTP client. The Servlet specification requires that files in WEB-INF
are not served directly to clients.