Spring RestTemplate streaming response into another request

后端 未结 2 605
感情败类
感情败类 2021-02-04 13:47

I am trying to stream the result of a file download directly into another post using spring\'s RestTemplate

My current approach is the following:

         


        
相关标签:
2条回答
  • 2021-02-04 14:03

    If you want to forward the response directly without ever holding it in memory, you have to directly write to the response:

    @RequestMapping(value = "/yourEndPoint")
    public void processRequest(HttpServletResponse response) {
        RestTemplate restTemplate = new RestTemplate();
    
        response.setStatus(HttpStatus.OK.value());
    
        restTemplate.execute(
            fileToDownloadUri,
            HttpMethod.GET,
            (ClientHttpRequest requestCallback) -> {},
            responseExtractor -> {
                IOUtils.copy(responseExtractor.getBody(), response.getOutputStream());
                return null;
            });
    }
    
    0 讨论(0)
  • 2021-02-04 14:17

    Since you tell RestTemplate to expect InputStreamResource it will try and use an appropriate converter to convert your message to a InputStreamResource. ( I'm guessing there is none that handles this as you want )

    You should be able to let it expect a Resource from where you can get an input stream and read that.

     import org.springframework.core.io.Resource;
    
     ResponseEntity<Resource> exchange = RestTemplate.exchange(url, HttpMethod.GET, new HttpEntity(httpHeaders), Resource.class);
     InputStream inputStream = exchange.getBody().getInputStream();
    

    using this you can write the response to somewhere else. Files.write(inputStream, new File("./test.json")); wrote the file for me, so I assume the inputstream can also be used somewhere else. ( I used Spring 4.3.5 )

    edit:

    As the OP states, this will still load the file in memory. Behind the scene the InputStream is a ByteArrayInputStream.

    The default RestTemplate and MessageConverters are not made for streaming content at all. You could write your own implementation of a org.springframework.web.client.ResponseExtractor and maybe a MessageConverter. In ResponseExtractor you have access to the org.springframework.http.client.ClientHttpResponse

    imho for your use case, you might be better of using Apache Httpcomponents HttpClient where you find HttpEntity#writeTo(OutputStream).

    0 讨论(0)
提交回复
热议问题