从SQL数据库通过Apache Camel将二进制文件流回端点

时间:2015-03-04 21:09:26

标签: java rest servlets streaming apache-camel

当我对我的Camel服务进行REST调用时,我试图从SQL数据库中获取一些varbinary数据。我可以将数据作为字节数组获取并将其设置为Camel Exchange的主体,然后Servlet将其作为原始字节返回给调用者(Web浏览器,应用程序,等等)。

我现在处于我想用流执行此操作而不是将所有字节保存在内存中的位置。如果我使用JdbcTemplate,那么即使我尝试返回.query并将其设置为InputStream,我在Exchange方法完成时也可以从结果集中获取连接和流。 {{1}}身体。这可以防止我从数据库中流式传输数据,直接通过Camel传回数据,然后再回到调用者。

如果我自己编写jdbc内容,我可以将流设置为交换机体,但是我不认为我有机会关闭连接和我打开的流,这样做,最终会耗尽资源。

我看过onCompletion,但我不知道如何使用它来关闭我没有参考的流和连接,而且我不确定这是否肯定会执行数据已流回调用者。

我使用Camel 2.14.1中的REST DSL和Servlet组件。有没有办法完成这个,而不是写一个文件,我稍后用某个定时任务清理它?我想避免这种情况,否则你会遇到竞争条件,在哑巴计时器清理数据之前将数据流回来。

1 个答案:

答案 0 :(得分:0)

实现此目的的方法是,在您查询数据库的bean中,从Connection获取ConnectionPool,创建PreparedStatement以获取您的任何列数据,并使用ResultSet.getBinaryStream执行它以请求您的二进制数据。

这会为您提供一个InputStream,您可以将其设置为Camel Exchange正文,如果您正在使用REST DSL,则必须在REST端点上设置RestBindingMode.off

将其设置为您的交换正文后,使用setProperty("your_name_here", closeableresource)将流,关联和结果集作为属性附加到您的交易所。

请注意,将这些设置为标头可能会导致Servlet将它们绑定到响应中,此外通常会有最大标头大小,这些大小不适合。

在错误情况下,bean中的错误处理应该处理清理连接等。

然后在REST端点调用的路由上,有一个onCompletion子句,该子句仅在REST调用的使用者完成时执行。在该子句中,调用Processor,它提取您之前为需要关闭的资源设置的属性,对其进行null检查并关闭它们。

对于缺少代码段感到抱歉,希望我有时间回到这一点,但上述内容应该足够了。

tl; dr:onCompletion 在通过连接传回所有流后执行,至少对于使用Apache Camel的Servlet