Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何通过流式rest服务巨大的文件?_Java_Spring - Fatal编程技术网

Java 如何通过流式rest服务巨大的文件?

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

我有两个SpringWeb应用程序:Application1和Application2。在Application1中,我在“”处有一个端点,它使用流式处理,以便在用户点击该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是流。是否有某种方法可以确保应用程序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。