Java 通过Apache Camel将SQL数据库中的二进制文件流式传输回端点
当对我的Camel服务进行REST调用时,我试图从SQL数据库中获取一些Java 通过Apache Camel将SQL数据库中的二进制文件流式传输回端点,java,rest,servlets,streaming,apache-camel,Java,Rest,Servlets,Streaming,Apache Camel,当对我的Camel服务进行REST调用时,我试图从SQL数据库中获取一些varbinary数据。我可以以字节数组的形式获取数据,并将其设置为Camel的主体Exchange,然后Servlet将其作为原始字节返回给调用者(web浏览器、应用程序等) 我现在想用一个流来实现这一点,而不是在内存中保存所有字节。如果我使用JdbcTemplate,当.query方法完成时,我可以从我的结果集获得的连接和流都会关闭,即使我尝试返回InputStream并将其设置为Exchange主体。这会阻止我将数据从
varbinary
数据。我可以以字节数组的形式获取数据,并将其设置为Camel的主体Exchange
,然后Servlet
将其作为原始字节返回给调用者(web浏览器、应用程序等)
我现在想用一个流来实现这一点,而不是在内存中保存所有字节。如果我使用JdbcTemplate
,当.query
方法完成时,我可以从我的结果集获得的连接和流都会关闭,即使我尝试返回InputStream
并将其设置为Exchange
主体。这会阻止我将数据从数据库直接通过Camel流式传输到调用者
如果我自己编写jdbc的东西,我可以在它打开时将流设置为exchange主体,但是我不认为我有机会关闭为此而打开的连接和流,并且最终会因此耗尽资源
我看过onCompletion,但我不知道如何使用它来关闭我没有参考的流和连接,我不确定在所有数据流回到调用方后是否一定会执行
我正在使用Camel2.14.1中的RESTDSL和Servlet组件。有没有什么方法可以在不写入文件的情况下完成这项工作,而我稍后会在某个地方使用定时任务来清理该文件?我希望避免这种情况,否则在哑计时器清除数据之前,您会有一个争用条件来流回数据。实现这一点的方法是,在您的bean中查询数据库,从
连接池
获取连接,创建PreparedStatement
以获取数据的任何列,并使用ResultSet.getBinaryStream
执行它以请求二进制数据
这将为您提供一个InputStream
,您可以将其设置为CamelExchange
body,如果您使用的是REST DSL,则必须在REST端点上设置RestBindingMode.off
将其设置为exchange主体后,使用setProperty(“此处为您的名称”,closeableresource)
将流、连接和结果集附加为exchange上的属性
请注意,将这些设置为头可能会导致Servlet
将它们绑定到响应中,此外,通常还有一个最大头大小,这些头大小不适合
在错误情况下,bean中的错误处理应该处理清除连接等问题
然后在REST端点调用的路由上,有一个onCompletion
子句,它只在REST调用的使用者完成时执行。在该子句中,调用一个处理器
,该处理器提取您以前为需要关闭的资源设置的属性,对它们进行null检查,然后关闭它们
对于缺少代码片段表示歉意,希望我有时间回到这里,但是上面的内容应该足够了
tl;dr:onCompletion
将在所有流通过连接传回后执行,至少对于使用Apache Camel的Servlet