当前位置: 首页 > 知识库问答 >
问题:

Rest模板将响应读取为流并传递给spring控制器(使用Rest模板获取InputStream)

锺离韬
2023-03-14

我有一个下载大尺寸zip文件的url。它以流的形式返回响应。虽然文件大小首先很大,但它返回200(HTTPSTATUK.OK)并继续下载。

我必须实现一个新的spring控制器,它通过rest模板调用上述url。我必须阅读rest模板返回的响应并将其传递给控制器。最初我是以下面的方式实现的

     @GetMapping("/export/downloadFile")
        public ResponseEntity<byte[]> downloadData(Model model,
                                                       @ModelAttribute(EXCEPTION_COLLECTOR) ExceptionCollector exceptionCollector,
                                                       @RequestParam("userName") String userName,
                                                       @RequestParam("startDate") Date startDate,
                                                       @RequestParam("endDate") Date endDate,
                                                       @RequestParam("reason") String reason) {

   URI uri = /building url here/;
    
    return restTemplate.exchange(uri, HttpMethod.GET, new HttpEntity<>(httpHeaders), byte[].class);
    
    }

因为我用的是ResponseEntity

我们是否有办法将响应读取为流并返回控制器。

我发现关于restTemplate的东西很少。处决

restTemplate.execute(uri,HttpMethod.GET,requestCallBack,clientHttpResponse -> {
                File ret = File.createTempFile("download", ".zip",new File("/Users/bokkavijay/Desktop"));
                StreamUtils.copy(clientHttpResponse.getBody(), new FileOutputStream(ret));
                return ret;
            });

上面的代码段可以将文件复制到本地,但这不是我需要的。

我们如何将clientHttpResponse中的流输送到控制器?

共有1个答案

杨凯旋
2023-03-14

我找到了工作实现

控制器

    @GetMapping("/readResponseAsStream")
        public ResponseEntity<StreamingResponseBody> downloadAsStream(Model model,HttpServletResponse response) {

             HttpHeaders httpHeaders=new HttpHeaders();
             httpHeaders.add("Transfer-Encoding","chunked");
             httpHeaders.add("Content-Type","x-zip-compressed");
             httpHeaders.add("Content-Disposition", "attachment;filename=sample.zip");

            ServletOutputStream servletOutputStream=response.getOutputStream();

            StreamingResponseBody downloadFile = out -> {
                 

                      RequestCallback requestCallBack=request->{
                            request.getHeaders().add(//Add headers here);
                      };

                      ResponseExtractor<ServletOutputStream> responseExtractor = clientHttpResponse -> {

                              //code snippet if you want to write response stream to HttpServletResponse
                              byte[] buff = new byte[800000];
                              int bytesRead = 0;
                                  while ((bytesRead = clientHttpResponse.getBody().read(buff)) != -1) {
                                    servletOutputStream.write(buff, 0, bytesRead);
                                    }
                              return servletOutputStream;


                              //Incase if you want to copy file to you local
                               File ret = File.createTempFile("download", ".zip",new File("Add Local system directory address here"));
                               StreamUtils.copy(clientHttpResponse.getBody(), new FileOutputStream(ret));

                               //You can copy the the clientHttpResponse.getBody() to ByteArrayInputStream and return
                               // Don't return clientHttpResponse.getBody() directly because rest template will close the inputStream(clientHttpResponse.getBody()) after .execute completed

                               //if you want to write restTemplate.execute in dao layer , pass servletOutputStream as a argument to method

                              };

                   restTemplate.execute(URL_ADDRESS,HttpMethod.GET,requestCallBack,responseExtractor);


            };


            return new ResponseEntity(downloadFile,httpHeaders,HttpStatus.OK);
}

如果你写的响应直接到HttpServlet响应,控制器下载文件时,我们在浏览器中访问

 类似资料:
  • 我有一个方法,调用一个endpoint来发布客户我怎么才能只得到消息"EMAIL ALREADY EXISTS"从响应体的Rest模板,以便在FacesContext中显示它 这是回应机构

  • Spring参考提到应该通过进行定制。如何用一个构建器管理来自多个IP地址的多个URI? 如何通过向所有全局添加,这是一个好的实践吗? 多谢帮忙。 我考虑为每个服务器设置一个。我不想手动执行此操作--我更喜欢使用Spring机制。 有人帮忙吗?

  • 我正在尝试使用spring的RestTemplate将文件下载结果直接流式传输到另一个帖子中 我目前的做法如下: 但是,在运行上述代码时,我遇到以下异常: 似乎响应总是作为处理的最后一步而结束。通过响应,关闭,流不再可处理。 我希望能够实现这个场景,而不必将文件完全保存在内存中或将其写入文件(如此处所述)。 非常感谢任何提示。

  • 问题内容: 尝试访问传递给模板的函数时出现错误: 有人可以让我知道我在做什么错吗? 模板文件(struct.tpl): 调用文件: 这是用于生成struct样板代码的程序(以防万一有人想知道为什么我要在模板中这样做)。 问题答案: 自定义函数需要在解析模板之前进行注册,否则解析器将无法分辨标识符是否为有效的函数名。模板被设计为可静态分析的,这是必需的。 您可以先使用创建一个新的未定义模板,并且除了

  • 相当新的Spring开发者.. 过去几天我一直在使用Spring,并设法使用JPA和Spring Rest创建了一个简单的CRUD API。现在,我希望能够灵活地改变返回的JSON的组成方式。 例如,我有以下简单实体: GET请求返回以下JSON: 现在我想删除部分并添加其他内容。 这在Spring可能吗? 课程: FaqsCategory(实体) FaqsCategoryRepository

  • 当我尝试执行请求时,我不断收到以下异常。对url的直接curl请求可以正常工作,但实际上不行。我正在尝试从端口上的服务调用端口上的服务。 密码 卷曲 错误