【问题标题】:Error streaming BLOB from Spring MVC controller从 Spring MVC 控制器流式传输 BLOB 时出错
【发布时间】:2018-04-28 15:33:48
【问题描述】:

我有一些二进制数据存储在 Postgres 的 Blob 中。我通过 JPA 使用数据库,但在这种情况下这并不重要。我有一个 spring MVC @Controller 应该能够通过端点提供这些数据。我想流式传输数据,因为为什么要将它全部加载到内存中。大致如下:

@Entity
class MyEntity {
    @Lob  
    Blob data;
}

@RequestMapping(...)
public InputStreamResource getResource(...) {
    return new InputStreamResource(myEntityRepository.findById(id).getData().getBinaryStream());
}

不幸的是,这给了我:

java.io.IOException:org.postgresql.util.PSQLException:错误:无效 大对象描述符:1

我知道为什么:当您使用 Blob 时,您需要 run in transaction。现在我已经尝试过:

  1. 注释整个控制器方法@Transactional - 没有帮助,因为当 Spring 开始将流复制到 servlet 响应中时,它已经在事务方面之外。 :'(

  2. 我还验证了如果我在控制器内部将输入流复制到byte[] 中,一切正常。但这不是流媒体。

byte[] data = IOUtils.toByteArray(myEntityRepository.findById(id).getData().getBinaryStream()); return new ByteArrayResource(data);

很明显,@Transactional 方面的问题是更接近控制器方法,即获取返回值并将其转换为 servlet 响应的方法。

有没有办法重新排序这些方面?还有其他解决方案吗?

谢谢!

编辑: 似乎它应该只需通过 @EnableTransactionManagement(order = Ordered.HIGHEST_PRECEDENCE) 就可以工作,不幸的是事实并非如此。可能是因为@EnableAspectJAutoProxy(proxyTargetClass = true)

编辑2: 这显然是一个更普遍的问题。 @RequestMapping 注释方法只返回 Stream 但只有在调用完成后 - 包括所有方面和 @Transactional - 返回的值(流)被进一步处理。所以事实上,我希望将事务扩展到实际调用控制器方法的类,可能是整个Servlet.doXXX 方法。没有好消息。

【问题讨论】:

  • 春季版?
  • 弹簧启动 1.5
  • 是否可以在 Spring Boot 2.0 中的 Spring Webflux 中迁移?

标签: java spring-mvc streaming blob


【解决方案1】:

原来我忽略了最简单但不太优雅的解决方案。我仍然可以将HttpServletResponseOutputStream 注入到控制器的方法中,并将Stream 复制到控制器的方法中。不如返回 InputStreamResource 好,但可以。

【讨论】:

    猜你喜欢
    • 2018-08-29
    • 1970-01-01
    • 2015-06-08
    • 2023-03-29
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    相关资源
    最近更新 更多