繁体   English   中英

Java Servlet在为调用存储过程的doGet()引发异常时出错

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

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

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,因为被覆盖的方法不会引发Exception,SQLException或NamingException。

new InitialContext()引发一个已检查的异常NamingException ,应将其捕获,或者正在使用此代码的方法应具有与其关联的throws子句。

由于要扩展HttpServlet并覆盖doGet方法,因此无法附加新的选中的Exception,因为这违反了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中的覆盖规则:

覆盖方法

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

你是对的。 您不能将异常添加到重写的方法的throws子句中。

而是将有问题的语句放在try / catch块中并处理错误。 如果没有其他问题,您可以将它们作为ServletException重新抛出。 例如:

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

最好的方法是使用@mprabhat和@QuantumMechanic给出的try-catch包装SQL代码。

如果您想知道为什么不可以

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

要么

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

谢谢大家不投票!!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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