英文:
Null pointer exception while retrieving list of items in servlets
问题
I have translated the provided code for you:
我是*servlets*的新手。我有一个名为*MenuServlet*的类,在这个类中,我调用*StoreController*类的*getMenu*函数。在这个*StoreController*类中,我连接了数据库并执行了查询。
以下是我附加的两个可能出错的类函数。我已经检查了连接,控制台上没有问题,我可以获取到项目列表。但是我收到了空指针异常。
Servlet.service() for servlet [jsp] threw exception
java.lang.NullPointerException
at org.apache.jsp.menu_jsp._jspService(menu_jsp.java:102)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:477)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:742)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:484)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:409)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:337)
at milkshake.servlets.MenuServlet.doGet(MenuServlet.java:63)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
```java
//这是menuservlet的doget函数
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html");
PrintWriter pw = response.getWriter();
pw.println("menuservlet");
StoreController sc = new StoreController();
try {
request.setAttribute("menu1", sc.getMenu());
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
RequestDispatcher dispatcher = request.getRequestDispatcher("menu.jsp");
dispatcher.forward(request, response);
}
public class StoreController {
static List<Milkshake> menuboard = new ArrayList<Milkshake>();
public List<Milkshake> getMenu() throws SQLException,
ClassNotFoundException {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String username = "sa";
String password = "123456abcd";
String url = "jdbc:sqlserver://localhost;databaseName=Milkshake";
Connection con;
con = DriverManager.getConnection(url, username, password);
String sql = "select * from dbo.Milkshake";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
menuboard.add(new Milkshake(rs.getInt(1),rs.getString(2), rs.getDouble(3)));
}
rs.close();
stmt.close();
con.close();
return menuboard;
}
}
<!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>Insert title here</title>
</head>
<body>
<h2>Menu</h2>
<h2>items:</h2>
<%List<Milkshake> list=(List<Milkshake>)request.getAttribute("menu1"); %>
<%for (Milkshake m:list){ %>
<%=m.getMilkshakeid()%>
<%=m.getName() %>
<%=m.getPrice() %>
<%} %>
<form action="AddServlet">
<button>addorder</button>
</form>
</body>
</html>
请注意,我已经将HTML代码从Java代码中分离出来以进行翻译。如果您需要进一步的帮助,请随时告诉我。
英文:
I am new to servlets. I have a class MenuServlet from where I call getMenu function of StoreController class. In this StoreController class I connected database and executed query.
Hereby i attached two classes functions where it may be wrong. I checked the connection also. when i consoled there is no problem i can get the list of items. But i am getting null pointer exception.
Servlet.service() for servlet [jsp] threw exception
java.lang.NullPointerException
at org.apache.jsp.menu_jsp._jspService(menu_jsp.java:102)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:477)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:742)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:484)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:409)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:337)
at milkshake.servlets.MenuServlet.doGet(MenuServlet.java:63)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
//this is doget function of menuservlet
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html");
PrintWriter pw = response.getWriter();
pw.println("menuservlet");
StoreController sc = new StoreController();
try {
request.setAttribute("menu1", sc.getMenu());
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
RequestDispatcher dispatcher = request.getRequestDispatcher("menu.jsp");
dispatcher.forward(request, response);
}
public class StoreController {
static List<Milkshake> menuboard = new ArrayList<Milkshake>();
public List<Milkshake> getMenu() throws SQLException,
ClassNotFoundException {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String username = "sa";
String password = "123456abcd";
String url = "jdbc:sqlserver://localhost;databaseName=Milkshake";
Connection con;
con = DriverManager.getConnection(url, username, password);
String sql = "select * from dbo.Milkshake";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
menuboard.add(new Milkshake(rs.getInt(1),rs.getString(2), rs.getDouble(3)));
}
rs.close();
stmt.close();
con.close();
return menuboard;
}
}
<!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>Insert title here</title>
</head>
<body>
<h2>Menu</h2>
<h2>items:</h2>
<%List<Milkshake> list=(List<Milkshake>)request.getAttribute("menu1"); %>
<%for (Milkshake m:list){ %>
<%=m.getMilkshakeid()%>
<%=m.getName() %>
<%=m.getPrice() %>
<%} %>
<form action="AddServlet">
<button>addorder</button>
</form>
</body>
</html>
答案1
得分: 1
感谢您的回复。从数据库检索时出现空指针异常的原因是:
- Mysql jar未添加到类路径。
- 连接对象未正确初始化,因此con对象本身为null。
- 只注册和加载驱动程序类一次。
- 如果不确定,对对象进行空值检查。
英文:
Thank you for your responses. The reasons for null pointer exception while retrieving from the database are
- Mysql jar is not added to class path.
- Connection object is not properly initialised so the con object itself is null
- register and load driver class only once
- Null check the objects if you are not sure
答案2
得分: 0
以下是您要翻译的内容:
"Probably your server is failing to load the JDBC driver class. In order to confirm it, I would debug the servlet code or at least put System.out.println(sc.getMenu())
before request.setAttribute("menu1", sc.getMenu())
."
"Apart from this, I can see multiple issues with your code:
- In the JSP, the
import
statement is missing. - It seems you have defined the servlet-mapping in
web.xml
. However, I recommend you use@WebServlet
annotation which is much simpler to use and removes the need for an additional file (web.xml
). - You should not declare
menuboard
asstatic
inStoreController
. This way, you are making it a class variable which means the value ofmenuboard
will be same for all instances ofStoreController
. If this variable is to be used by justgetMenu()
I recommend you make it local togetMenu()
. - If you are closing
Connection
, you do not need to closeResultset
andStatement
explicitly. They will be automatically closed when theConnection
is closed."
"Given below is an mvce using MySQL database:"
Milkshake.java:
"package beans;"
public class Milkshake {
private int milkshakeid;
private String name;
private double price;
public Milkshake(int milkshakeid, String name, double price) {
this.milkshakeid = milkshakeid;
this.name = name;
this.price = price;
}
public int getMilkshakeid() {
return milkshakeid;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
StoreController.java:
"package milkshake.db;"
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import beans.Milkshake;
public class StoreController {
public List<Milkshake> getMenu() throws SQLException, ClassNotFoundException {
List<Milkshake> menuboard = new ArrayList<>();
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbase", "root", "Hello@123");
String sql = "select * from Milkshake";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
menuboard.add(new Milkshake(rs.getInt(1), rs.getString(2), rs.getDouble(3)));
}
con.close();
return menuboard;
}
}
AddServlet.java:
"package servlets;"
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import milkshake.db.StoreController;
@WebServlet("/AddServlet")
public class AddServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
StoreController sc = new StoreController();
try {
request.setAttribute("menu1", sc.getMenu());
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
RequestDispatcher dispatcher = request.getRequestDispatcher("menu.jsp");
dispatcher.forward(request, response);
}
}
menu.jsp:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@page import="java.util.List,beans.Milkshake"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h2>Menu</h2>
<h2>items:</h2>
<%
List<Milkshake> list = (List<Milkshake>) request.getAttribute("menu1");
%>
<%
for (Milkshake m : list) {
%>
<%=m.getMilkshakeid()%>
<%=m.getName()%>
<%=m.getPrice()%>
<br>
<%
}
%>
</body>
</html>
Output:
英文:
Probably your server is failing to load the JDBC driver class. In order to confirm it, I would debug the servlet code or at least put System.out.println(sc.getMenu())
before request.setAttribute("menu1", sc.getMenu())
.
Apart from this, I can see multiple issues with your code:
- In the JSP, the
import
statement is missing. - It seems you have defined the servlet-mapping in
web.xml
. However, I recommend you use@WebServlet
annotation which is much simpler to use and removes the need for an additional file (web.xml
). - You should not declare
menuboard
asstatic
inStoreController
. This way, you are making it a class variable which means the value ofmenuboard
will be same for all instances ofStoreController
. If this variable is to be used by justgetMenu()
I recommend you make it local togetMenu()
. - If you are closing
Connection
, you do not need to closeResultset
andStatement
explicitly. They will be automatically closed when theConnection
is closed.
Given below is an mvce using MySQL database:
Milkshake.java:
package beans;
public class Milkshake {
private int milkshakeid;
private String name;
private double price;
public Milkshake(int milkshakeid, String name, double price) {
this.milkshakeid = milkshakeid;
this.name = name;
this.price = price;
}
public int getMilkshakeid() {
return milkshakeid;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
StoreController.java:
package milkshake.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import beans.Milkshake;
public class StoreController {
public List<Milkshake> getMenu() throws SQLException, ClassNotFoundException {
List<Milkshake> menuboard = new ArrayList<>();
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbase", "root", "Hello@123");
String sql = "select * from Milkshake";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
menuboard.add(new Milkshake(rs.getInt(1), rs.getString(2), rs.getDouble(3)));
}
con.close();
return menuboard;
}
}
AddServlet.java:
package servlets;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import milkshake.db.StoreController;
@WebServlet("/AddServlet")
public class AddServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
StoreController sc = new StoreController();
try {
request.setAttribute("menu1", sc.getMenu());
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
RequestDispatcher dispatcher = request.getRequestDispatcher("menu.jsp");
dispatcher.forward(request, response);
}
}
menu.jsp:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="java.util.List,beans.Milkshake"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h2>Menu</h2>
<h2>items:</h2>
<%
List<Milkshake> list = (List<Milkshake>) request.getAttribute("menu1");
%>
<%
for (Milkshake m : list) {
%>
<%=m.getMilkshakeid()%>
<%=m.getName()%>
<%=m.getPrice()%>
<br>
<%
}
%>
</body>
</html>
Output:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论