我目前正在处理一个Web应用程序,但它无法运行。下面是我到目前为止servlet和Java类的代码。我检查了提供数据库连接的代码,我知道这是正确的。我相信servlet或Java类有问题。
以下是我收到的错误:
HTTP Status 500 -
type Exception report
message
description The server encountered an internal error that prevented it from fulfilling this request.
exception
java.lang.NullPointerException
music.data.ConnectionPool.freeConnection(ConnectionPool.java:41)
music.data.ProductDB.selectProducts(ProductDB.java:159)
music.admin.ProductAdminController.displayProducts(ProductAdminController.java:74)
music.admin.ProductAdminController.doGet(ProductAdminController.java:36)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
这是Java Servlet:
package music.admin;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import music.business.Product;
import music.data.ProductDB;
public class ProductAdminController extends HttpServlet {
/* Comment this method out when using this class with a database
* instead of a text file.
*/
//@Override
//public void init() {
//ProductIO.init(getServletContext()
// .getRealPath("/WEB-INF/products.txt"));
//}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// get current action
String action = request.getParameter("action");
if (action == null) {
action = "displayProducts"; // default action
}
// perform action and set URL to appropriate page
String url = "/index.jsp";
if (action.equals("displayProducts")) {
url = displayProducts(request, response);
} else if (action.equals("displayProduct")) {
url = displayProduct(request, response);
} else if (action.equals("addProduct")) {
url = "/product.jsp";
} else if (action.equals("deleteProduct")) {
url = deleteProduct(request, response);
}
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// get current action
String action = request.getParameter("action");
if (action == null) {
action = "displayProducts"; // default action
}
// perform action and set URL to appropriate page
String url = "/index.jsp";
if (action.equals("updateProduct")) {
url = updateProduct(request, response);
} else if (action.equals("deleteProduct")) {
url = deleteProduct(request, response);
}
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
}
private String displayProducts(HttpServletRequest request,
HttpServletResponse response) {
ArrayList<Product> products = (ArrayList) ProductDB.selectProducts();
request.setAttribute("products", products);
return "/products.jsp";
}
private String displayProduct(HttpServletRequest request,
HttpServletResponse response) {
String productCode = request.getParameter("productCode");
Product product;
if (productCode == null || productCode.isEmpty()) {
product = new Product();
} else {
product = ProductDB.selectProduct(productCode);
}
request.setAttribute("product", product);
return "/product.jsp";
}
private String addProduct(HttpServletRequest request,
HttpServletResponse response) {
return "/product.jsp";
}
private String updateProduct(HttpServletRequest request,
HttpServletResponse response) {
String productCode = (String) request.getParameter("productCode");
String description = (String) request.getParameter("description");
String priceString = (String) request.getParameter("price");
double price;
try {
price = Double.parseDouble(priceString);
} catch (NumberFormatException e) {
price = 0;
}
Product product = (Product) request.getAttribute("product");
if (product == null) {
product = new Product();
}
product.setCode(productCode);
product.setDescription(description);
product.setPrice(price);
request.setAttribute("product", product);
String message = "";
if (product.getPrice() <= 0) {
message = "You must enter a positive number for the price without "
+ "any currency symbols.";
}
if (product.getDescription().length() == 0) {
message = "You must enter a description for the product.";
}
if (product.getCode().length() == 0) {
message = "You must enter a code for the product.";
}
request.setAttribute("message", message);
String url;
if (message.isEmpty()) {
if (ProductDB.exists(product.getCode())) {
ProductDB.updateProduct(product);
} else {
ProductDB.insertProducts(product);
}
url = displayProducts(request, response);
} else {
url = "/product.jsp";
}
return url;
}
private String deleteProduct(HttpServletRequest request,
HttpServletResponse response) {
String productCode = request.getParameter("productCode");
Product product = ProductDB.selectProduct(productCode);
request.setAttribute("product", product);
String url;
String yesButton = request.getParameter("yesButton");
if (yesButton != null) {
ProductDB.removeProduct(product);
url = displayProducts(request, response);
} else {
url = "/confirm_product_delete.jsp";
}
return url;
}
}
这是Java类:
package music.data;
import java.sql.*;
import java.util.*;
import music.business.Product;
public class ProductDB
{
//This method returns null if a product isn't found.
public static Product selectProduct(String productCode)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String query = "SELECT * FROM Product " +
"WHERE ProductCode = ?";
try
{
ps = connection.prepareStatement(query);
ps.setString(1, productCode);
rs = ps.executeQuery();
if (rs.next())
{
Product p = new Product();
p.setCode(rs.getString("ProductCode"));
p.setDescription(rs.getString("ProductDescription"));
p.setPrice(rs.getDouble("ProductPrice"));
return p;
}
else
{
return null;
}
}
catch(SQLException e)
{
System.out.println(e);
return null;
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
//This method will return 0 if productID isn't found.
public static int selectProductID(Product product)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String query = "SELECT ProductID FROM Product " +
"WHERE ProductCode = ?";
try
{
ps = connection.prepareStatement(query);
ps.setString(1, product.getCode());
rs = ps.executeQuery();
rs.next();
int productID = rs.getInt("ProductID");
return productID;
}
catch(SQLException e)
{
System.out.println(e);
return 0;
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
//This method returns null if a product isn't found.
public static Product selectProduct(int productID)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String query = "SELECT * FROM Product " +
"WHERE ProductID = ?";
try
{
ps = connection.prepareStatement(query);
ps.setInt(1, productID);
rs = ps.executeQuery();
if (rs.next())
{
Product p = new Product();
p.setCode(rs.getString("ProductCode"));
p.setDescription(rs.getString("ProductDescription"));
p.setPrice(rs.getDouble("ProductPrice"));
return p;
}
else
{
return null;
}
}
catch(SQLException e)
{
System.out.println(e);
return null;
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
//This method returns null if a product isn't found.
public static ArrayList<Product> selectProducts()
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String query = "SELECT * FROM Product";
try
{
ps = connection.prepareStatement(query);
rs = ps.executeQuery();
ArrayList<Product> products = new ArrayList<Product>();
while (rs.next())
{
Product p = new Product();
p.setCode(rs.getString("ProductCode"));
p.setDescription(rs.getString("ProductDescription"));
p.setPrice(rs.getDouble("ProductPrice"));
products.add(p);
}
return products;
}
catch(SQLException e)
{
System.out.println(e);
return null;
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
public static void insertProducts(Product product)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String query = "INSERT INTO product (ProductCode, ProductDescription, ProductPrice)"
+ "VALUES"
+ "('"+product.getCode()+"','"+product.getDescription()+"','"+product.getPriceNumberFormat()+"');";
try
{
ps = connection.prepareStatement(query);
ps.execute(query);
}
catch(SQLException e)
{
System.out.println(e);
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
public static void updateProduct(Product product)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String query = "UPDATE product SET productDescription ='"+product.getDescription()+"',"+"ProductPrice='"+product.getPriceNumberFormat()+"' WHERE ProductCode='"+product.getCode()+"';";
try
{
ps = connection.prepareStatement(query);
ps.execute(query);
//rs = ps.executeQuery();
}
catch(SQLException e)
{
System.out.println(e);
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
public static boolean exists(String productCode) {
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String query = "SELECT productCode FROM Product " +
"WHERE ProductCode = ?";
try {
ps = connection.prepareStatement(query);
ps.setString(1, productCode);
rs = ps.executeQuery();
return rs.next();
} catch (SQLException e) {
System.out.println(e);
return false;
} finally {
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
public static void removeProduct(Product product)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String query = "DELETE FROM product WHERE ProductCode='"+product.getCode()+"';";
try
{
ps = connection.prepareStatement(query);
ps.execute(query);
}
catch(SQLException e)
{
System.out.println(e);
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
}
以下是连接池的代码:
package music.data;
import java.sql.*;
import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class ConnectionPool {
private static ConnectionPool pool = null;
private static DataSource dataSource = null;
private ConnectionPool() {
try {
InitialContext ic = new InitialContext();
dataSource = (DataSource) ic.lookup("java:/comp/env/jdbc/music");
} catch (NamingException e) {
System.out.println(e);
}
}
public static synchronized ConnectionPool getInstance() {
if (pool == null) {
pool = new ConnectionPool();
}
return pool;
}
public Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
System.out.println(e);
return null;
}
}
public void freeConnection(Connection c) {
try {
c.close();
} catch (SQLException e) {
System.out.println(e);
}
}
}
DBUtil Class
package music.data;
import java.sql.*;
public class DBUtil
{
public static void closeStatement(Statement s)
{
try
{
if (s != null)
s.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
}
public static void closePreparedStatement(Statement ps)
{
try
{
if (ps != null)
ps.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
}
public static void closeResultSet(ResultSet rs)
{
try
{
if (rs != null)
rs.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
从您的问题和提供的代码中,我认为可以重新审视几点,看看我们是否有任何问题。
您已使用Class DBUtil关闭结果集和语句对象。
DBUtil似乎不是标准类。可能使用来自apache的DBUtils将是一个更好的选择。鉴于DBUtil似乎没有标准实现,请提供DBUtil的实现以及其他类。
此外,使用DButil关闭结果集和语句会丢失对称性,但还有一些其他方法可以关闭连接。我建议使用DBUtils.close()或closequietly()来关闭连接。
此外,在您的实现中,初始连接池大小似乎不清楚。通过使用ds.setInitialPoolSize()显式将poolsize设置为更高的数字。
这样做应该主要解决问题,或者说明问题的清晰度。
答案 1 :(得分:0)
既然您已经发布了代码,问题非常明确:您收到NullPointerException,因为您尝试在空连接上调用close()
。
为什么连接为空?
因为getConnection()方法返回null:
try {
return dataSource.getConnection();
} catch (SQLException e) {
System.out.println(e);
return null;
}
在上面的代码中,您尝试从DataSource获取连接,如果数据源通过抛出异常来表示您无法获得连接,则基本上忽略该异常,并返回null。
结果:不是得到一个明确的SQLException来解释为什么你不能从DataSource获得连接,你会在一个不相关的方法中得到一个模糊的NullPointerException,它不会告诉你关于它的任何信息。实际问题。
不要这样做。如果你真的不想在调用getConnection()
时处理检查的SQLException,那么将SQLException包装成运行时异常。然后,您将有一个明确的消息和堆栈跟踪指示问题的确切位置和位置:
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeSQLException(e);
}
public class RuntimeSQLException extends RuntimeException {
public RuntimeSQLException(Throwable cause) {
super(cause);
}
}