Search code examples
javaspringrestspring-mvcresttemplate

Get opened input stream from rest template for large file processing


I am looking for a way to get opened input stream from rest template - I was trying to used ResponseExtractor, but the stream is getting closed before returning, as written here:

https://jira.spring.io/browse/SPR-7357

"Note that you cannot simply return the InputStream from the extractor, because by the time the execute method returns, the underlying connection and stream are already closed"

I hope that there is a way and I will not have to write to my output stream directly in the rest template.


Solution

  • I didn't find a way to do it, the stream is always getting closed. As a workaround I created the following code:

    public interface ResourceReader {
        void read(InputStream content);
    }
    

    with the following implementation:

    public class StreamResourceReader implements ResourceReader {
    
    private HttpServletResponse response;
    
    public StreamResourceReader(HttpServletResponse response) {
        this.response = response;
    }
    
    @Override
    public void read(InputStream content) {
        try {
            IOUtils.copy(content, response.getOutputStream());
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }
    }
    

    then in controller:

    @RequestMapping(value = "document/{objectId}")
    public void getDocumentContent(@PathVariable String objectId, HttpServletResponse response) {
        ResourceReader reader = new StreamResourceReader(response);
        service.readDocumentContent(objectId, reader);
    }
    

    call to rest template:

    restTemplate.execute(uri, HttpMethod.GET, null,
                new StreamResponseExtractor(reader));
    

    and the string response extractor:

    @Override
    public ResponseEntity extractData(ClientHttpResponse response) throws IOException {
        reader.read(response.getBody());
        return null;
    }
    

    and it works like a charm! :)