我的设置:我创建了一个REST服务(Jersey/Dropwizard),可以从数据库中流式传输大量内容。在GET操作期间,服务通过连接池接入数据库,将数据打包成流,并执行一些即时转换,以各种编码(CSV、JSON等)呈现请求的数据。数据库连接的生命周期与流的生命周期相关联,只有当流关闭时,数据库连接才会被释放。
流转换由编码器类执行,该类返回StreamingOutput,然后将其传递给响应对象。编码器当前处理流完全消耗时的资源关闭。
我的问题是:由于StreamingOutput没有实现AutoCloseable,当输出仅被部分消耗时,可能会发生连接泄漏。
我有时观察到,陈旧的活动连接正在连接池中堆积,我怀疑它们是由中止的HTTP连接引起的。如下所示,当前代码处理try块中发生的异常。我无法处理的是return语句之后发生的异常,我不知道如何将资源关闭的任何指令附加到响应对象。
我的问题是:在请求终止后(定期或由于错误),如何通知响应对象关闭特定资源?或者:当请求上下文结束时,有没有更好的方法来安全地关闭任何相关资源?
@GET
//@Produces(...)
html" target="_blank">public Response streamData(
@PathParam("key") String key,
// ... other params
) {
//decode and validate params
Stream<Pojo> ps = null;
try {
// connect to db and obtain data stream for <key>
ps = loadData(db, key);
// apply detailed encoding instrunctions and create a StreamingOutput
final StreamingOutput stream = Encoder.encodeData(ps, encodingArgs);
return Response.ok(stream).build();
} catch (Exception e) {
closeOnException(ps); // wrapper for ps.close();
throw e;
}
}
您可以在方法HttpServletResponse中添加:
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Object streamData(
@PathParam("key") String key,
@Context HttpServletResponse response,
// ... other params
) {
...
response.getOutputStream().write(....)
response.flushBuffer();
response.getOutputStream().close();
return null;
}
我从dropwizard邮件列表中收到了一个很好的答案,解决了我的问题,我想在这里引用它,以防有人遇到同样的问题。
https://groups.google.com/forum/#!topic/dropwizard用户/62GoLDBrQuo
引用肖恩的回答:
Jersey支持CloseableService,允许您在请求完成时注册要关闭的可关闭对象:
public Response streamData(..., @Context CloseableService closer) {
...
closer.add(closeable);
return Response.ok(...).build();
}
我想返回一个临时重定向,使用AsyncACK。 下面的“工作”(因为没有错误),但似乎不是异步的(它一次处理一个请求)。 这应该工作吗?如果我明确需要像https://jersey.github.io/documentation/latest/async.html#d0e9895一样启动一个新线程,返回响应是什么样子的?
我试图理解异步响应在Jersey上的工作方式。我阅读了新泽西文档(https://jersey.java.net/documentation/latest/async.html)的第10章,但它对我的问题没有帮助。这里关于stackoverflow的研究也没有得出令人满意的答案(这一点我可以理解)。 我试图做的与本文中的一个问题类似(使用http状态202进行异步操作)。我想使用HTML表单文档将
我使用的是Jersey客户端v2。16(Dropwizard 0.8.0的可传递依赖项,我也在使用它)。 当实体被读取为时,我不知何故对响应的关闭机制感到困惑。文件规定: 此外,如果实体被读入InputStream(通过response.readEntity(InputStream.class))中,则连接将保持打开状态,直到您完成对InputStream的读取。在这种情况下,应该在从InputS
我决定在这部分替换Web.XML: 我指向servlet容器Jersey,它将接受对REST-Controllers的请求,表明在启动时有必要扫描路径com . skillsimprover . REST examples . REST上的包REST,并表明资源的所有方法和类的基URI都填充了/api/* 从 JAX-RS 2.x 版本开始,可以使用应用程序类或资源配置类来注册包和资源。 我执行了
关于HTTP连接关闭,我有两个问题: > 如果一个客户端通过连接发送一个HTTP请求:靠近HTTP服务器,那么在客户端收到响应后,HTTP服务器还是客户端有责任发送TCP FIN? 如果客户端发送了一个格式错误的HTTP请求,而服务器发送了一个400错误的请求,那么最好的做法是通过服务器关闭连接(即使HTTP请求有connection:keep alive),还是保持连接仍然处于活动状态? 提前感
当我在Jersey中有一个监听POST请求的方法,并且当我想从中获取数据的方法中有一个InputStream作为参数时,我需要关闭这个InputStream还是Jersey会处理这个问题? 我没有找到任何相关信息。不久前,我读过使用JAX-RS 2.0的RESTful Java,我不记得是否有人提到过它。现在浏览一下,我发现了几个代码示例,并且流没有关闭。我觉得没必要,但我想问问。