如何通过流媒体休息服务巨大的文件?

时间:2015-09-03 04:24:23

标签: java spring

我有2个Spring Web应用程序:Application1和Application2。在Application1中,我的端点位于" http://application1/getbigcsv"它使用流式传输,以便在用户点击该URL时向用户提供巨大的150MB CSV文件。

我不希望用户直接点击Application1,而是点击Application2。 如果我在Application2的控制器中有以下方法

@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正在进行流式传输。有没有什么方法可以确保application2将以流方式从application1的休息端点回送相同的数据?或者上面的方法实际上是在" Streaming"方法已经因为Application1将其端点作为流媒体服务?

3 个答案:

答案 0 :(得分:14)

首先:您可以但不能使用该方法签名。

不幸的是,您还没有展示如何在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 get 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();
    }
}

Here是我真实世界的榜样。开始阅读“有兴趣说出我已经取得的成就,特别是:”

答案 1 :(得分:1)

java.ws.rs.core包中,您有以下课程:StreamingOutputResponseBuilder

不确定它是否会对您有所帮助,但您可以尝试。

示例:

@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();
} 

答案 2 :(得分:0)

将方法返回类型更改为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));
}