【发布时间】:2017-09-19 17:31:53
【问题描述】:
我看过很多关于如何使用StreamingOutput 的例子。就我而言,我想用它从数据库查询中流式传输 ResultSet。
ResultSet rs = (ResultSet) obj;
StreamingOutput stream = new StreamingOutput() {
@Override
public void write(OutputStream os) throws IOException,
WebApplicationException {
ResultSetFormatter.outputAsJSON(os, rs);
res.close();
}
};
return Response.ok(stream).build();
在这个意义上,write 方法定义包括一个throws IOException, WebApplicationException。我的问题出现在哪里。我需要正确关闭与数据库、结果集等的连接。如果在执行流式传输时抛出异常,我不知道如何捕获它。
我尝试了以下代码,但它不是有效代码,因为 IOException 不是从 try-catch 块中抛出的。
try {
.... launch request to database ...
ResultSet rs = (ResultSet) obj;
StreamingOutput stream = new StreamingOutput() {
@Override
public void write(OutputStream os) throws IOException,
WebApplicationException {
if (accept.equals("application/json") {
ResultSetFormatter.outputAsJSON(os, rs);
} else {
ResultSetFormatter.outputAsXML(os, rs);
}
res.close();
}
};
return Response.ok(stream).build();
} catch (IOException | WebApplicationException e) {
// Do cleanup
}
我该如何继续?是否可以正确清理所有内容?我什至认为在 write 方法中包含所有数据处理,但问题是,如果不修复,我无法设置响应的内容类型。
TIA
编辑 1:我使用的是基于 Jena 而不是 SQL 数据库的 SPARQL 语句。根据查询的类型,我得到不同类型的响应(模型、结果集或布尔值)。然后每个都有不同的有效内容类型,所以在执行或分析查询之前我无法设置响应的内容类型。
【问题讨论】:
-
你想在这里完成什么?这段代码在什么地方运行?看起来您正在尝试复制延迟加载的数据。可能有更好的方法来实现这一点。
-
我有一个很大的结果集,否则我必须在本地存储在内存中。我想将它直接流式传输到客户端。如果发生某些事情,就会出现问题,因为我必须关闭结果集等以释放资源。我不明白你懒惰的数据加载。
-
查看 thread 了解延迟加载
-
我不认为是延迟加载。正如我告诉过你的,我不想将整个结果集存储在内存中来创建字符串。我更喜欢直接流式传输。
-
您似乎希望在使用数据时加载数据,而不是加载所有内容然后将数据传递给您的 Web 服务的响应,即延迟加载。在任何情况下,除了语义,通常您希望您的服务根据每个请求处理数据库事务。这将使您的结果保持活力,直到它们被消耗掉。如果不知道您是否正在使用任何框架,或者这是一个 servlet 还是其他东西,就很难进入细节。
标签: java http outputstream resource-cleanup