英文:
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 
importstatement is missing. - It seems you have defined the servlet-mapping in 
web.xml. However, I recommend you use@WebServletannotation which is much simpler to use and removes the need for an additional file (web.xml). - You should not declare 
menuboardasstaticinStoreController. This way, you are making it a class variable which means the value ofmenuboardwill 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 closeResultsetandStatementexplicitly. They will be automatically closed when theConnectionis 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 
importstatement is missing. - It seems you have defined the servlet-mapping in 
web.xml. However, I recommend you use@WebServletannotation which is much simpler to use and removes the need for an additional file (web.xml). - You should not declare 
menuboardasstaticinStoreController. This way, you are making it a class variable which means the value ofmenuboardwill 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 closeResultsetandStatementexplicitly. They will be automatically closed when theConnectionis 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:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。




评论