Search code examples
javaandroidspringretrofit2

Download File using Retrofit 2.0 and Spring Server


I had an Android application working with Retrofit 1.9 and a Spring Server. Android application could download files perfectly. I am trying to migrate to Retrofit 2.0.

Retrofit 1.9 Code

Controller Server:

@RequestMapping(value = GET_MAP , method = RequestMethod.GET)
public void getMap(@PathVariable("filename")String filename
            ,HttpServletResponse response) throws IOException {
        Files.copy(filename + ".zip", response.getOutputStream());
}

Android Interface API

@Streaming
@GET(GET_MAP)
public Response getMap(@Path("filename") long id);

So, after Googling for migrating in order to download files in Retrofit 2.0 I have to use Call<ResponseBody> in my Android Interface API. I tried something like this:

OPTION 1 Controller Server Code

@RequestMapping(value = GET_MAP , method = RequestMethod.GET)
public void getMap(@PathVariable("filename")String filename
            ,HttpServletResponse response) throws IOException {
        Files.copy(filename + ".zip", response.getOutputStream());
}

OPTION 2 Controller Server Code

@RequestMapping(value = GET_MAP , method = RequestMethod.GET)
public @ResponseBody HttpServletResponse getMap(@PathVariable("filename")String filename
            ,HttpServletResponse response) throws IOException {
        Files.copy(filename + ".zip", response.getOutputStream());
return response;
}

Android Interface API

@Streaming
@GET(GET_MAP)
public Call<ResponseBody> getMap(@Path("filename") long id);

But using these two options the response length gives me -1:

response.body().contentLength() = -1

How do I have to migrate the Controller method?


Solution

  • After trying several configurations for the response on the server, this has worked for me:

    1. Get the File as new File

    2. Use the org.springframework.core.io.FileSystemResource.FileSystemResource library to pass the File as a ResponseBody.

      @RequestMapping(value = GET_MAP , method = RequestMethod.GET)
      public @ResponseBody Resource getMap(@PathVariable("filename")String filename ,HttpServletResponse response) throws IOException {
          File file = new File(filename + ".zip");
          return new FileSystemResource(file);
      }