简体   繁体   中英

How can I easily call a java class (which queries a database) and return usable results to a JSP?

I'm new to learning JSPs and Servlets. I have a Java class which calls a stored procedure and return a list of states from a database (this is my test case while I learn, other more complex actions will come later). The list of states should be returned to a JSP for display/use in a form, etc... For now, I'm happy to just get the data printing via the JSP page to know it is there.

However, when I call the Java code from the JSP, it appears that the result object is returned as null and thus no data is accessible. I've tried to return the data as a ResultSet object as well, but the results are the same. I do know the stored procedure works when called from SQL. Additionally I have the Java code as a servlet that responds to a doPost request and that works fine...

What might I be missing / failing to understand? Is this possible?

package edu.XXXX.ais.userapp;

import java.sql.*;
import java.util.*;

public class DBQueries {

    public static Vector<String> getStatesList() {
        Vector<String> results = new Vector<String>();
        Connection con = null;  
        try {

            // Example of executing a stored procedure
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection ("jdbc:mysql://hostname:3306/dbName","username","password");
            CallableStatement cs = con.prepareCall("{call getStatesList()}");
            ResultSet rs = cs.getResultSet();

            while (rs.next()) {
                results.add(rs.getString(1));
            }
        } catch (SQLException e) {
            System.err.println("Servlet could not display records." + e);

        } catch (ClassNotFoundException e) {
            System.err.println("JDBC driver not found." + e);

        } finally {
            try {
                if (con != null) {
                    con.close();
                    con = null;
                }

            } catch (SQLException e) {
                System.err.println(e);
            }
        }
        return results;
    }
}

JSP page that calls the above Java code (expects to be able to receive results...)

<html>
<head>
<title>Foo</title>
</head>

<body>
<h3>List of states via a servlet call to the database</h3>
<%@ page import="java.util.*" %>
<%@ page import="edu.XXXX.ais.userapp.DBQueries" %>

<%
    Vector rs = DBQueries.getStatesList();
    if (rs != null)
        for (int index = 0; index < rs.size(); index++) {
            out.println("Name : " + (String) rs.get(index));
        }
%>

</body>
</html>

The resulting Tomcat errors are as follows:

org.apache.jasper.JasperException: An exception occurred processing JSP page /states.jsp at line 12

9: <%@ page import="edu.XXXX.ais.userapp.DBQueries" %>
10: 
11: <%
12:     Vector rs = DBQueries.getStatesList();
13:     if (rs != null)
14:         for (int index = 0; index < rs.size(); index++) {
15:             out.println("Name : " + (String) rs.get(index));


Stacktrace:
    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:568)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:470)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
root cause

java.lang.NullPointerException
    edu.XXXX.ais.userapp.DBQueries.getStatesList(Unknown Source)
    org.apache.jsp.states_jsp._jspService(states_jsp.java:75)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

The exception tells you where to look:

edu.XXXX.ais.userapp.DBQueries.getStatesList(Unknown Source)

There's a null reference in that method. I'd recommend testing that without the JSP and use a debugger.

You don't close your Statement or ResultSet . That will lead to grief. Close them in reverse order of creation, just like you did the Connection .

For starters, please stop putting scriptlet code in your JSP. That's 1999 style; don't do it.

The right thing to do is to learn JSTL and only have your JSP do display tasks.

Let the JSP talk to a servlet that intercedes on its behalf with the database.

Use the app server to set up the data source. You shouldn't have connection information inside your code.

Forget about servlets and JSPs for now. Start with the data layer.

Write that using POJOs, test it, get it working, and put it aside.

Then write a servlet that takes in an HTTP request, validates and binds the parameters, uses your data access layer to talk to the database, and then put the response in request or session scope for the page to display.

It's called Model-2 MVC. That's the way to write Java web apps.

I'd write that DBUtils class something more like this:

package edu.XXXX.ais.userapp;

import java.sql.*;
import java.util.*;

public class DBQueries {

    public static List<String> getStates(Connection connection) throws SQLException {
        List<String> states = new ArrayList<String>();
        CallableStatement cs = null;
        ResultSet rs = null;
        try {
            cs = connection.prepareCall("{call getStatesList()}");
            boolean hasResultSet = cs.execute();
            rs = cs.getResultSet();    
            while (rs.next()) {
                states.add(rs.getString(1));
            }
        } finally {
            close(rs);
            close(cs);
        }
        return states;
    }

    public static void close(ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(Statement st) {
        try {
            if (st != null) {
                st.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(Connection conn) {
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Write a JUnit test to prove that your DBQueries works:

package edu.XXX.ais.userapp;

public class DBQueriesTest {

    // You have to initialize this; I'm deliberately leaving out some details.
    private Connection connection;

    @Test
    public void testGetStates() {
        List<String> actual = DbQueries.getStates(this.connection);
        List<String> expected = { "CT", "NY" };  // whatever
        Assert.assertEquals(expected, actual);
    }
}

In your sample code, the CallableStatement is not executed before cs.getResultSet() , so rs will be null, and then NullPointerException will occur when executing rs.next() .

CallableStatement cs = con.prepareCall("{call getStatesList()}");
boolean bIsResultSetOrNot = cs.execute (); // <-- missed
ResultSet rs = cs.getResultSet(); 

Make sure the statement is executed, and make sure the execute result is ResultSet not an update count.

The exception stacktrace shows you have a null pointer in method DBQueries.getStatesList(). Surround the try block in the method with Exception and try to see which line is throwing it. My guess is Connection object is null.

If that is true check the value of "hostname" which you are passing while acquiring a connection.

You are trying pass a Vector of String a Vector. You method is Vector<String> getStatesList() you are making reference a NULL .

Into ../Apache Tomcat/webapps/work find you class compiled of JSP. Look at the error in those line of JSP.

Please for making connection to Data Base using Spring Core JDBCTemplate class, is very nice class for those and you forget to close connections. :) Nice

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