java - 在 Java Web App 中检索大量数据并将其下载到客户端
问题描述
鉴于:
- 一个在websphere上运行的 web 应用程序和一个带有大表的oracle 数据库
- 一个 jsf 网站,允许用户下载csv文件中的部分数据。
- 访问数据库的正常方式是通过 JPA (openJPA)
- 潜在的文件下载大小高达500MB到 1GB
问题:
如何使用户能够通过其客户端硬盘驱动器上的 Web 应用程序从数据库下载如此大的数据导出,而不会出现 OutOfMemory 异常/存储/缓冲服务器上的完整数据
解决方案
尝试在单个 HTTP 请求中执行此操作可能会遇到许多限制。
流式处理和异步处理是两种可能的解决方案。
流媒体
看起来JPA 2.2 增加了流媒体支持。为了防止出现内存不足的情况,您可能需要调整 JVM,还可能需要调整 JDBC 提取大小以平衡数据库性能和客户端性能。
然后,您可以将结果流式传输/缓冲回客户端。
但是这种方法存在问题。当网络连接瞬间中断时会发生什么?有人不小心关闭了他们的浏览器,提供 Content-Length 响应标头来帮助衡量剩余时间等?更好的方法是:
异步
这些步骤可能是这样的:
- 客户端向服务器提交请求。
- 服务器启动一个异步进程(web worker 或 JMS)。
- 异步进程生成文件并将其临时存储在文件系统上。
- 该过程完成后,它会向客户发送一封电子邮件以获取他们的文件。这称为索赔检查。它也可以是返回的 URL,而不是电子邮件,用户随后可以刷新以查看他们的文件何时可以提取。
- 经过“合理”的时间后,文件被删除。
这种方法可以配置为允许自动恢复功能并消除等式中的网络不确定性和浏览器选项卡关闭。总体而言,它还减轻了必须处理重新请求的压力。使用 JMS 还可以让您水平而不是垂直扩展此解决方案。
推荐阅读
- asp.net-web-api - 尝试访问 IIS 10 中托管的 asp.net 核心应用程序时出现内部服务器错误
- html - 推送 ul li 的每个子级别
- python-3.x - 比较两个目录和删除非重复基名的最快 Python 方法
- azure - Microsoft 监控代理 (MMA) 和 OMS 代理之间的区别
- c# - 如何在 SqlKata 中将多个 WHERE 子句连接在一起?
- c# - System.Text.GetBytes 缩短了我的数据,修复了吗?
- node.js - 在 POST 请求结束之前无法访问最近保存的数据 - node.js
- reactjs - 何时/何地在 React 中设置新状态
- python - 返回 JSON 数组中的最小值
- c# - 无法将参数绑定到 .net 核心