抛出doGet()调用存储过程的异常时出现Java Servlet错误

时间:2012-05-18 02:39:56

标签: java database servlets

任何人都知道如何解决以下错误

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

我从这个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() {  
  }         
}

如果我尝试替换

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

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

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

它们都会产生错误,说我无法覆盖doGet,因为重写的方法不会抛出异常,SQLException或NamingException。

3 个答案:

答案 0 :(得分:2)

new InitialContext()抛出一个已检查的异常NamingException,该异常应该被捕获,或者您使用此代码的方法应该有一个与之关联的throws子句。

由于您正在扩展HttpServlet并覆盖doGet方法,因此无法附加新的已检查异常,因为它违反了Java中的覆盖法则。

而是将代码放在try catch块中并捕获NamingException

所以而不是

Context context = new InitialContext();

将此替换为

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

类似地dataSource.getConnection抛出一个应该被捕获或重新抛出的已检查异常SQLException,再一次你不能将新的已检查异常添加到你的doGet方法中,因为覆盖规则你必须明确地捕获它。

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

Java中的覆盖规则:

Overridden Method

  • 参数不得更改
  • 返回类型除协变(子类型)返回
  • 外无法更改
  • 例外可以减少/消除。不得抛出新的/更广泛的检查异常
  • 访问权限不得限制更多。可以限制较少。
  • 调用在运行时
  • 调用哪种方法基于对象类型

答案 1 :(得分:1)

你是对的。您不能向重写方法的throws子句添加例外。

相反,将有问题的语句放在try / catch块中并处理错误。如果没有别的,你可以将它们重新抛出为ServletException。例如:

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

答案 2 :(得分:1)

使用@mprabhat&amp;提供的try-catch包装SQL代码@QuantumMechanic是最好的方式..

如果您想知道为什么不能这样做

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

OR

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

..这是因为当你重写方法时 - 要记住两个重要的事情。

  • 重写方法可以有一个更自由的访问器。例如:如果超类方法被声明为protected int add(...),你可以用public int add(...)覆盖,反之则不可能。
  • 重写方法必须声明超类的异常相同或子类型。例如..如果超类方法声明为public int add() throws IllegalArgumentException,则重写方法可以具有以下语法。 public int add() throws NumberFormatException,但它不能有更广泛的语法,如public int add() throws Exception

感谢大家不要贬低!!