4

I use spring android in a thread dedicated to execute spring android requests.

I can't achieve to abort a request launched from spring android (a getForObject for instance).

I tried to :

  • reach the underlying input stream to close but it is completely wrapped in springandroid restemplate and can't be accessed from outside
  • interrupt the thread
  • get the request factory of the rest template and call destroy
  • get the connection manager of the factory and call shutdown
  • change the rest template factory's http client
  • change the rest template factory's request factory

but I can't abort a request and send a new one quickly. The first one has to reach its timeout.

How could I "kill" a spring android request a get a stable rest template to send a new request ?

Thanks in advance.

Snicolas
  • 37,840
  • 15
  • 114
  • 173
  • that might be stupid idea but... what about wrapping restTemplate request inside AsyncTask? – Piotr Jul 08 '14 at 18:15
  • @Piotr, did you have a look at http://stackoverflow.com/a/13082084/693752 ? – Snicolas Jul 09 '14 at 06:53
  • I'm confused on that. I saw many examples showing how to use AsyncTask to make a HTTP requests, such as downloading zip file. How does it differ for using it as a wrapper for RestTemplate.exchange? – Piotr Jul 10 '14 at 00:38

1 Answers1

3

I suggest using ResponseExtractor.

you can call execute method of RestTemplate such as below.

    File file = (File) restTemplate.execute(rootUrl.concat("/vocasets/{vocasetId}/{version}"), HttpMethod.GET, requestCallabck,
            responseExtractor, uriVariables);

ResponseExtractor has extractData method. you can take body inputstream from extractData method through getBody() of response.

Extend ResponseExtractor for canceling your request.

Good luck.

In my case, I've used Listener way.

static class FileResponseExtractor implements ResponseExtractor<File> {
            ...

    public void setListener(ReceivingListener listener) {
        this.listener = listener;
    }

    @Override
    public File extractData(ClientHttpResponse response) throws IOException {
        InputStream is = response.getBody();

        long contentLength = response.getHeaders().getContentLength();

        long availableSpace = AvailableSpaceHandler.getExternalAvailableSpaceInMB();
        long availableBytes = AvailableSpaceHandler.getExternalAvailableSpaceInBytes();
        Log.d(TAG, "available space: " + availableSpace + " MB");

        long spareSize = 1024 * 1024 * 100;
        if(availableBytes < contentLength + spareSize) {
            throw new NotEnoughWritableMemoryException(availableSpace);
        }

        File f = new File(temporaryFileName);
        if (f.exists())
            f.delete();
        f.createNewFile();

        OutputStream o = new FileOutputStream(f);

        listener.onStart(contentLength, null);
        boolean cancel = false;
        try {
            byte buf[] = new byte[bufferSize];
            int len;
            long sum = 0;
            while ((len = is.read(buf)) > 0) {
                o.write(buf, 0, len);
                sum += len;
                listener.onReceiving(sum, len, null);

                cancel = !listener.onContinue();
                if(cancel) {
                    Log.d(TAG, "Cancelled!!!");
                    throw new CancellationException();
                }
            }
        } finally {
            o.close();
            is.close();
            listener.onFinish(null);

            if(cancel) {
                f.delete();
            }
        }

        return f;

    }

}
Louis Huh
  • 301
  • 3
  • 13
  • 1
    And how could I interrupt the request properly using a ResponseExtractor ? – Snicolas Oct 20 '12 at 06:14
  • I've appended how to implement FileResponseExtractor – Louis Huh Oct 31 '12 at 13:05
  • is there a way to add such an extractor to all requests made by a rest template instance ? I got a lib where devs can use a rest template in the way they want and I would like to be able to cancel their requests on demand, whatever way they use the rest template. – Snicolas Nov 01 '12 at 07:44
  • In my case is.close(); is waiting until all bytes are downloaded. Can you suggest anything to fix it? – valijon Sep 27 '20 at 03:37