【问题标题】:Handling unexpected end of requests in servlets处理 servlet 中的请求意外结束
【发布时间】:2011-03-01 16:21:06
【问题描述】:

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

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

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

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

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

提前感谢您的帮助,

拉斐尔

【问题讨论】:

    标签: java exception servlets jdbc thread-abort


    【解决方案1】:

    通常,只要在response.getOutputStream() 上调用了flush()close(),而另一端已中止连接,就会抛出IOException

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

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

    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) {}
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    相关资源
    最近更新 更多