2

我目前正在使用 Jersey/Tomcat 开发 REST Web 服务(但欢迎使用通用 Servlet/Container 答案)。如果客户端对从 MySQL 连接返回大量数据的服务执行一些 GET 请求。

为了避免任何 OOM 异常,我对 MySQL 使用流模式。

但是,如果客户端在加载期间中止请求,则 MySQL 连接不会关闭。之后,服务器将不再处理任何其他请求,因为一次只能处理一个“流”请求。

所以问题是:每当请求在我的服务器上结束时(正常或异常),我怎样才能得到通知。我可以注册某种听众吗?还是使用 UncaughtExceptionHandler ?

我已经看到了很多关于在 Jersey 中处理异常以将它们转换为“响应”的事情,但没有任何事情可以处理请求的过早结束。我猜 Jersey 或 Tomcat 可能会在没有通知的情况下简单地破坏我的线程。我可以在我的方法的关键部分捕获一些异常以了解何时发生此类线程中断吗?

在此先感谢您的帮助,

拉斐尔

4

1 回答 1

2

通常,每当或在另一方中止连接时被调用时,IOException都会抛出an 。flush()close()response.getOutputStream()

通常,关闭数据库连接(和其他资源)应该发生在打开它的finally块的try块中,以便在出现异常时无论如何都会关闭它。

总结一下,这个例子应该做到:

String search = getItSomehow();
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;

try {
    connection = database.getConnection();
    statement = connection.prepareStatement(SQL_FIND);
    statement.setString(1, search);
    resultSet = statement.executeQuery();

    if (resultSet.next()) {
        response.setContentType(resultSet.getString("contentType"));
        response.setContentLength(resultSet.getInt("contentLength")); // Optional.
        BufferedInputStream input = null;
        BufferedOutputStream output = null;
        try {
            input = new BufferedInputStream(resultSet.getBinaryStream("content"));
            output = new BufferedOutputStream(response.getOutputStream());
            byte[] buffer = new byte[1024];
            for (int length; (length = input.read(buffer)) > 0;) {
                output.write(buffer, 0, length);
                output.flush();
            }
        } finally {
            if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
            if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
        }
    } else {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
    }
} catch (SQLException e) {
    throw new ServletException("Something failed at SQL/DB level.", e);
} finally {
    if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
    if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
    if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
于 2010-06-09T14:44:21.170 回答