我需要创建一个 CSV 导出来传输数据(而不是将其完全加载到内存中):
@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("/export/csv")
public Response streamCsv() throws InvalidDataException {
final StreamingOutput streamingOutput =
os -> productManager.exportCsv(new RequestContext(1, 1), os);
return Response
.ok(streamingOutput, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=product_export.csv")
.build();
}
这工作正常,
但是当流崩溃时(由于流处理过程中出现任何类型的错误),端点仍将返回 HTTP 状态代码 200(成功),并且不会向调用者返回错误(如 HTTP 状态代码 500) )
调用者会觉得 CSV 文件有效,但在发生错误之前它可能只包含尽可能多的行。
注意:重要的是要注意,完整的数据不应该!随时加载到内存中。允许将小块数据加载到内存中。因此,包含
os.toByteArray()
的解决方案是不够的。
我让它以某种方式像我期望的那样工作。
我们可以切断请求连接,这样客户端至少会得到某种发生错误的信息(中止连接)。
我仍然会等待并希望有更好的解决方案......
@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("/export/xlsx")
public void streamXlsx(@Context HttpServerRequest request, @Context HttpServerResponse response) {
try {
response.setChunked(true); // Enable chunked responses
response.putHeader("Content-Type", MediaType.APPLICATION_OCTET_STREAM);
response.putHeader("Content-Disposition", "attachment; filename=product_export.xlsx");
productManager.exportXlsx(new RequestContext(1, 1), new HttpServerResponseOutputStream(response));
} catch (Exception e) {
response.write("ERROR DURING PROCESSING!");
try {
Thread.sleep(500L);
} catch (InterruptedException e2) {
//
}
request.connection().close();
try {
Thread.sleep(1000L);
} catch (InterruptedException e2) {
//
}
}
}