简体   繁体   中英

Java Servlet error in throwing exceptions for doGet( ) calling stored procedure

Anyone know how to fix the following errors

unreported exception javax.naming.NamingException; must be caught or declared to be thrown Context context = new InitialContext();

Auth.java:46: unreported exception java.sql.SQLException; must be caught or declared to be thrown conn = ds.getConnection();

that I get from this java servlet?

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.sql.SQLException;
import oracle.jdbc.OracleTypes;

public class ABC extends HttpServlet {

  @Override
  public void init(ServletConfig config) throws ServletException {
    super.init(config);
  }

  protected void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    Connection conn;
    CallableStatement cs;

    String xy = req.getParameter("xy");
    String zz = req.getParameter("zz");

    // call stored procedure
    Context context = new InitialContext();
    DataSource ds = (DataSource)context.lookup("jdbc/mypool");
    conn = ds.getConnection();
    cs = conn.prepareCall( "{call mysproc (?,?)}" );
    cs.setString(1, xy);
    cs.setString(2, zz);
    cs.execute();

    if ( conn != null ) {
      try { conn.close(); } catch ( Exception ex ) {}
      conn = null;
    }

    // Set the content type (MIME Type) of the response.
    res.setContentType("text/html");

    // Write the HTML to the response
    PrintWriter out = res.getWriter();
    out.println("<html>");
    out.println("<head>");
    out.println("<title>my title</title>");
    out.println("</head>");
    out.println("<body>");
    out.println("<h2>my header</h2>");
    out.println("my body text<br/>");
    out.println("</body>);
    out.println("</html>");
    out.flush();
    out.close();
  }

  public void destroy() {  
  }         
}

If I try to replace

  protected void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

with

  protected void doGet(HttpServletRequest req, HttpServletResponse res)
    throws Exception {

or

  protected void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException, SQLException, NamingException {

they both produce errors saying I cannot override doGet, as overridden method does not throw Exception, or SQLException, or NamingException.

new InitialContext() throws a checked exception NamingException , which should either be caught or the method where you are using this code should have a throws clause associated with it.

Since you are extending HttpServlet and overriding doGet method you cannot attach new checked Exception, as it is against the law of overriding in Java.

Instead place the code inside a try catch block and catch NamingException .

So instead of

Context context = new InitialContext();

replace this by

Context context = null;
try {
    context = new InitialContext();
} catch(NamingException exp){
    //Handle Exception
}

Similarly dataSource.getConnection throws a checked exception SQLException which should be caught or rethrown, once again you cannot add new checked exception to your doGet method because of rules of overriding you will have to catch it explicitly.

try {
    DataSource ds = (DataSource)context.lookup("jdbc/mypool");
    conn = ds.getConnection();
    cs = conn.prepareCall( "{call mysproc (?,?)}" );
    cs.setString(1, xy);
    cs.setString(2, zz);
    cs.execute();

} catch ( SQLException exp ) {
  //Handle your exception
} finally {  
  if (conn != null ) {
      try {
         conn.close(); 
      } catch(SQLException sqlExp){
         // Handle your exception     
      }
      conn = null;
    }
}

Rules of Overriding in Java:

Overridden Method

  • Arguments Must not change
  • Return type Can't change except for covariant (subtype) returns
  • Exceptions Can reduce/eliminate. Must not throw new/broader checked exceptions
  • Access Must not be more restrictive. Can be less restrictive.
  • Invocation Which method to call is based on object type, at runtime time

You are correct. You cannot add exceptions to the overridden method's throws clause.

Instead, put the statements in question in a try / catch block and deal with the errors. If nothing else, you can rethrow them as a ServletException . For example:

Context context;
try {
    context = new InitialContext();
}
catch (NamingException e) {
    throw new ServletException(e);
}

Wrapping the SQL code with try-catch as given by @mprabhat & @QuantumMechanic is the best way to go..

If you were wondering why can't you do

protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws Exception {

OR

protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException, SQLException, NamingException {

.. it is because when you are overriding a method - there two important things to keep in mind..

  • The overriding method can have a more liberal accessor.. example: if the super class method is declared protected int add(...) , you can override with public int add(...) , the reverse is not possible.
  • The overriding method must declare the same or a sub-type of the super class's exceptions.. for example.. if the super class method is declared public int add() throws IllegalArgumentException , then the overriding method can have the following syntaxes.. public int add() throws NumberFormatException , but it cannot have a more broader syntax like public int add() throws Exception .

Thanks everyone for not downvoting!!

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