Stanislav
Stanislav

Reputation: 441

Spring: Post request with InputStreamResource

I have some InputStream and want to do post request using RestTempalte from spring-web.

public void postRequest(InputStream in){
    MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<>();
    parameters.add("file", new InputStreamResource(inputStream) {
        @Override
        public String getFilename(){
            return "some_name";
        }
    });

    HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(parameters);

    restTemplate.postForEntity(SOME_ENDPOINT, httpEntity, String.class)
}

When i invoke this method the IllegalStateException is occurred.

Exception in thread "main" java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times

In source code getInputStream() method from InputStreamResource we can see:

public InputStream getInputStream() throws IOException, IllegalStateException {
    if (this.read) {
        throw new IllegalStateException("InputStream has already been read - " +
                "do not use InputStreamResource if a stream needs to be read multiple times");
    }
    this.read = true;
    return this.inputStream;
}

How can i initialize InputStreamResource for my purpose? What do i miss?

Upvotes: 3

Views: 3458

Answers (1)

Stanislav
Stanislav

Reputation: 441

I am resolving it by overriding getContentLenght()

public void postRequest(InputStream in){
    MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<>();
    parameters.add("file", new InputStreamResource(inputStream) {
        @Override
        public String getFilename(){
            return "some_name";
        }

        @Override
        public long contentLength() throws IOException {
            return -1;
        }
    });

   HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(parameters);

   restTemplate.postForEntity(SOME_ENDPOINT, httpEntity, String.class)
}

Because native method contentLength() invoke getInputStream() to calculate length. And when invoke getInputStream() second time to take content from stream we get exception.

Upvotes: 5

Related Questions