我正在使用Java 8,Spring 4.3.x和Tomcat 7。
下面是我的代码,用于以块的形式从数据库中流式传输大量数据。
public ResponseEntity<StreamingResponseBody> streamRecords(HttpServletRequest request,
HttpServletResponse response,....)
throws Exception {
int recordSize = 5000;
int pageSize = 1000;
StreamingResponseBody responseBody = outputStream -> {
byte[] bytes = null;
for (int skip = 0 ; skip <= recordSize ; skip += pageSize) {
logger.error("SKIP: " + skip);
try {
JsonObject records = new JsonObject();
.
.//somewhere down the call is below code
.//dbCursor = dbCollection.find().skip(skip).limit(pageSize);
.
.
.
bytes = records.toString().getBytes();
outputStream.write(bytes);
outputStream.flush();
logger.error("BYTE LENGTH: " + bytes.length);
} catch (Exception e) {
logger.error("Exception occured while streaming records: " + e.getMessage() + "\n", e);
outputStream.close();
}
}
outputStream.close();
};
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=sample.csv")
.contentType(MediaType.APPLICATION_JSON)
.body(responseBody);
}
注意:所使用的输出流为CoyoteOutputStream.java
实际输出如下,
2019-05-14/15:48:30.850/IST[MvcAsync1] ERROR - SKIP: 0
2019-05-14/15:48:49.596/IST[MvcAsync1] ERROR - BYTE LENGTH: 282462
2019-05-14/15:48:49.606/IST[MvcAsync1] ERROR - SKIP: 1000
2019-05-14/15:49:07.777/IST[MvcAsync1] ERROR - BYTE LENGTH: 565633
2019-05-14/15:49:07.793/IST[MvcAsync1] ERROR - SKIP: 2000
2019-05-14/15:49:26.426/IST[MvcAsync1] ERROR - BYTE LENGTH: 849231
2019-05-14/15:49:26.433/IST[MvcAsync1] ERROR - SKIP: 3000
2019-05-14/15:49:45.595/IST[MvcAsync1] ERROR - BYTE LENGTH: 1132467
2019-05-14/15:49:45.625/IST[MvcAsync1] ERROR - SKIP: 4000
2019-05-14/15:50:03.962/IST[MvcAsync1] ERROR - BYTE LENGTH: 1416003
2019-05-14/15:50:03.996/IST[MvcAsync1] ERROR - SKIP: 5000
2019-05-14/15:50:24.028/IST[MvcAsync1] ERROR - BYTE LENGTH: 1699420
预期的输出结果如下。
2019-05-14/15:48:30.850/IST[MvcAsync1] ERROR - SKIP: 0
2019-05-14/15:48:49.596/IST[MvcAsync1] ERROR - BYTE LENGTH: 282462
2019-05-14/15:48:49.606/IST[MvcAsync1] ERROR - SKIP: 1000
2019-05-14/15:49:07.777/IST[MvcAsync1] ERROR - BYTE LENGTH: 292462
2019-05-14/15:49:07.793/IST[MvcAsync1] ERROR - SKIP: 2000
2019-05-14/15:49:26.426/IST[MvcAsync1] ERROR - BYTE LENGTH: 282462
2019-05-14/15:49:26.433/IST[MvcAsync1] ERROR - SKIP: 3000
2019-05-14/15:49:45.595/IST[MvcAsync1] ERROR - BYTE LENGTH: 292462
2019-05-14/15:49:45.625/IST[MvcAsync1] ERROR - SKIP: 4000
2019-05-14/15:50:03.962/IST[MvcAsync1] ERROR - BYTE LENGTH: 282462
2019-05-14/15:50:03.996/IST[MvcAsync1] ERROR - SKIP: 5000
2019-05-14/15:50:24.028/IST[MvcAsync1] ERROR - BYTE LENGTH: 292462
字节必须是当前块的新副本,但在我写入outputStream时,它又会以某种方式占用以前的块。根据recordSize,我期望有5000条记录,但是我却获得21000条记录。
任何建议都会很有帮助。