【问题标题】:Jersey - Returning stream from ResultSetJersey - 从 ResultSet 返回流
【发布时间】:2012-03-10 00:52:43
【问题描述】:

我有一个带有 CLOB 字段的表 (MySQL MediumText)。

我想向该 CLOB 返回一个输入流。 我的资源代码如下所示:

@GET
public StreamingOutput getAsStream(int id) {
  try {
    // prepare the statement object
    ResultSet rs = stmt.executeQuery();
    if (rs.next()) return new StreamingOutput() {
      public void write(OutputStream outputStream) throws ... {
        copy(rs.getBinaryStream(1), outputStream);
      }
    }
  }
  finally {
    rs.close();
    stmt.close();
    connection.close();
  }
}

看起来不太对劲。在 Jersey 有机会将流写入响应之前,代码会关闭数据库资源(结果集、语句和连接)。

我可以在StreamingOutput.write 方法中关闭数据库资源。但它也感觉不对 - 我让一些外部容器关闭我的资源。

我能想到的最后一个想法是将整个流读入内存然后发送。我当然不想这样做。

那么,有人有更好的主意吗?

我检查了Return a file using Java Jersey,但没有多大帮助。

谢谢, 多伦

【问题讨论】:

    标签: java database jersey


    【解决方案1】:

    是的,您的代码将不起作用。您在方法中创建了一个匿名内部类,然后将其作为返回对象交给容器。新类中的 write 对象直到您的方法完成后的某个时间才会真正被调用,此时您当然已经关闭了所有连接。

    从概念上讲,尝试直接从数据库流式传输可能不是一个好主意。您不希望在客户端决定消耗输入流的时间内保持打开连接。最好的办法是将数据读入内存,然后将该数据流式传输到客户端。

    【讨论】:

    • 当然我的代码不应该工作,这就是我在这里发布问题的原因:-)。顺便说一句,代码确实有效。我猜是因为我正在使用连接池,所以连接并没有真正关闭。无论如何,流式 blob 听起来对我来说是一种足够常见的操作。我认为它可能会得到泽西岛的支持。但我猜您关于在实际上取决于客户端的一段时间内保持连接打开的论点胜诉。
    • @Perception,但是如果来自数据库的数据是一个巨大的数据集,比如大约一百万条记录,那么我想直接从数据库中流式传输会很好吗?
    • 一次性返回数百万条记录对于我编写过的任何系统来说都不是一个用例。 但是假设您遇到了必须这样做的情况,那么您应该对数据进行分页(使用限制),而不是尝试一次全部流式传输。
    猜你喜欢
    • 2013-10-19
    • 2012-11-03
    • 2020-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    相关资源
    最近更新 更多