Java 如何通过流式rest服务巨大的文件?
我有两个SpringWeb应用程序:Application1和Application2。在Application1中,我在“”处有一个端点,它使用流式处理,以便在用户点击该URL时将一个150MB的巨大CSV文件返回给用户 我不希望用户直接点击Application1,而是点击Application2。 如果我在Application2的控制器中有以下方法Java 如何通过流式rest服务巨大的文件?,java,spring,Java,Spring,我有两个SpringWeb应用程序:Application1和Application2。在Application1中,我在“”处有一个端点,它使用流式处理,以便在用户点击该URL时将一个150MB的巨大CSV文件返回给用户 我不希望用户直接点击Application1,而是点击Application2。 如果我在Application2的控制器中有以下方法 @RequestMapping(value = "/large.csv", method = GET, produces = "text/c
@RequestMapping(value = "/large.csv", method = GET, produces = "text/csv")
@ResponseStatus(value = HttpStatus.OK)
public String streamLargeCSV() {
// Make an HTTP Request to http://application1/getbigcsv
// Return its response
}
我担心的是上面所说的不是“流”,而Application1是流。是否有某种方法可以确保应用程序2将以流式方式从应用程序1的rest端点返回相同的数据?或者上面的方法实际上已经在“流”方法中返回了内容,因为Application1将其端点作为流服务?首先:您可以,但不能使用该方法签名 不幸的是,您还没有展示如何在app1中生成该CSV文件,这是否是真正的流。让我们假设它是 您的签名将如下所示:
@RequestMapping(value = "/large.csv", method = GET, produces = "text/csv")
@ResponseStatus(value = HttpStatus.OK)
public void streamLargeCSV(OutputStream out) {
// Make an HTTP Request to http://application1/getbigcsv
// Return its response
}
现在我们必须首先从app1获取输入流。将Apache HttpClient用于您的HttpEntity
。此实体有一个writeTo(OutputStream)
方法,该方法将接收您的out
参数。它将阻塞,直到所有字节被消耗/流化。完成后,释放所有HttpClient资源
完整代码:
@RequestMapping(value = "/large.csv", method = GET, produces = "text/csv")
@ResponseStatus(value = HttpStatus.OK)
public void streamLargeCSV(OutputStream out) {
// Make an HTTP Request to http://application1/getbigcsv
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("http://application1/getbigcsv");
CloseableHttpResponse response = httpclient.execute(httpGet);
try {
HttpEntity entity = response.getEntity();
// Return its response
entity.writeTo(out);
} finally {
response.close();
}
}
这是我真实世界的例子。开始阅读“有趣的是,我在这方面取得了哪些成就:在
java.ws.rs.core
包中,您有类:StreamingOutput
和ResponseBuilder
不确定它是否对你有帮助,但你可以试试
例如:
@Produces("application/octet-stream")
public Response doThings () {
...
StreamingOutput so;
try {
so = new StreamingOutput() {
public void write(OutputStream output) {
…
}
};
} catch (Exception e) {
...
}
ResponseBuilder response = Response.ok(so);
response.header("Content-Type", ... + ";charset=utf-8");
return response.build();
}
将方法返回类型更改为
ResponseEntity
,并按如下方式返回:
@GetMapping("/download")
public ResponseEntity<?> fetchActivities(
@RequestParam("filename") String filename) {
String string = "some large text"
InputStream is = new ByteArrayInputStream(string.getBytest());
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=large.txt");
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
return ResponseEntity.ok().headers(headers).body(new InputStreamResource(is));
}
@GetMapping(“/download”)
公众反应及活动(
@RequestParam(“文件名”)字符串(文件名){
String=“一些大文本”
InputStream is=new ByteArrayInputStream(string.getBytest());
HttpHeaders=新的HttpHeaders();
headers.add(HttpHeaders.CONTENT_处置,“附件;文件名=large.txt”);
headers.add(HttpHeaders.CONTENT\u TYPE、MediaType.APPLICATION\u OCTET\u STREAM\u VALUE);
返回ResponseEntity.ok().headers(headers).body(新的InputStreamResource(is));
}
您可以在CloseableHttpResponse上使用try with resources,以获得较少的样板文件。@approxValue这是真的。请随意将我的代码重新编译为Java7。他没有使用Jersey/JAX-WS。