Monika
Monika

Reputation: 195

rest api to download a file returns contents of file as a response without downloading it

    @GET
        @Path("/{loginId}")
        @Produces(MediaType.APPLICATION_OCTET_STREAM)
        public Response downloadExportedFile(@PathParam("loginId") String loginId) {
                File file = new File("D://abc.txt");
            Response.ResponseBuilder response = Response.ok((Object) file);
            response.header("Content-Disposition", "attachment; filename=newfile.txt");
response.type(MediaType.APPLICATION_OCTET_STREAM_TYPE);
            return response.build();
        }

This gives response as a content of file and not downloading it

Upvotes: 4

Views: 22960

Answers (2)

Harry Coder
Harry Coder

Reputation: 2740

Your code here is the API you are implementing and it returns the content of the file. Downloading your file should be done from a client by generating a new file after you get the content. For instance, with the HttpClient lib, you will get this code:

CloseableHttpClient client;
HttpGet request;
HttpResponse response;
HttpEntity entity;

try {
    client = HttpClientBuilder.create().build();
    request = new HttpGet(URI);
    response = client.execute(request);
    entity = response.getEntity();  

    // The file not found, or is not available
    if(response.getStatusLine().getStatusCode() == 404) {
        throw new CustomException("The URI is not valid");
    } else {
        InputStream is = entity.getContent();
        try (FileOutputStream fos = new FileOutputStream(new File(newFilePath))) {
            int inByte;
            while((inByte = is.read()) != -1) {
                fos.write(inByte);
            }
        }
        is.close();
        client.close();
    }
} catch(IOException  e) {
    e.printStackTrace();
}

If you want the file to be directly downloaded when you call the URL, you have to give the complete path with the name of the file : http://yourhost/yourfile.txt, and of course the file should be available on the server. Behind this URL, it is just a href HTML tag, that will point on your file. In your API, your URL will looks something like this : @Path("/{loginId}/{file}"), where {file} stands for the file you want to download.

Upvotes: 0

Dawid Kubicki
Dawid Kubicki

Reputation: 190

Monika if you use spring I recommend return response entity resource with headers something like this

 @GetMapping("/api/config)
    fun config(@PathVariable id: String): ResponseEntity<Resource> {
        val config = someService.getConfig(hotelId = id)
        val resource InputStreamResource(objectMapper.writeValueAsString(config)
                     .byteInputStream(Charsets.UTF_8))

    val responseHeaders = HttpHeaders()
    responseHeaders.add("content-disposition", 
    "attachment;filename=config.json")
    responseHeaders.add("Content-Type",MediaType.APPLICATION_OCTET_STREAM_VALUE)

    return ResponseEntity.ok()
        .headers(responseHeaders)
        .contentType(MediaType.parseMediaType("application/octet-stream"))
        .body(resource)
}

Here you have some other answer about

Content-Disposition and Content Type

The frontend should not have an impact on downloading file.

Upvotes: 1

Related Questions