简体   繁体   中英

JSP Servlet Web Application

I am currently working on a web application and it is not working. Below is the code that I have so far for the servlet and the Java class. I have checked the code that provides the connection to the database and I know that is correct. I believe there is something wrong with the servlet or the Java class.

Here is the error I am receiving:

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)

This is the 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;
    }    
}

Here is the Java Class:

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);
        }
    } 

}

Here is the code for the Connection Pool:

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();
        }
    }
}

From your question and the provided code, I think there are few points that could be revisited to see if we have any issue there.

  1. You have used Class DBUtil to close resultset and statement object.

    • DBUtil does not seem to be a standard class. Probably using DBUtils from apache would be a better alternative. Given that DBUtil does not seem to have a standard implementation, provide implementation of DBUtil along with the other Classes.

    • Also, the symmetry is lost by using DButil to close resultset and statement, but some other means for closing connection. I would suggest using DBUtils.close() or closequietly() for closing the connection.

  2. Also, in your implementation the initial connection pool size seems unclear. By explicitly setting the poolsize to a higher number using ds.setInitialPoolSize().

    • Additionally, Set the maximumPoolsize and preferredPoolSize if you want.

Doing this should mostly solve the problem, or give clarity regarding the issue.

Now that you've posted the code, the problem is very clear: You get a NullPointerException because you're trying to call close() on a null connection.

Why is the connection null?

Because the getConnection() method returns null:

    try {
        return dataSource.getConnection();
    } catch (SQLException e) {
        System.out.println(e);
        return null;
    }

In the above code, you try to get a connection from the DataSource, and if the datasource signals that you can't get one by throwing an exception, you basically ignore the exception, and return null instead.

The result: instead of getting a clear SQLException explaining why you can't get a connection from the DataSource, you get an obscure NullPointerException later, in an unrelated method, that doesn't tell you anything about the actual problem.

Don't do that. If you really don't want to deal with checked SQLException when calling getConnection() , then wrap the SQLException into a runtime exception. You'll then have a clear message and stack trace indication what and where the problem really is:

    try {
        return dataSource.getConnection();
    } catch (SQLException e) {
        throw new RuntimeSQLException(e);
    }

public class RuntimeSQLException extends RuntimeException {
    public RuntimeSQLException(Throwable cause) {
        super(cause);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM