1

I have web-service method which returns a byte[], so I did this to force the download of the returned file

 final byte[] content = axisService.getWebFileContent(pieceJointe.getVlidnlfy());

 if (content != null) {

   final Map<String, Object> lrFile = new HashMap<>(2);
   lrFile.put("CONTENT", content);
   lrFile.put("MIMETYPE", "application/octet-stream");
   response.reset();
   response.resetBuffer();
   response.setContentType("application/force-download");
   response.setHeader("Content-Transfer-Encoding", "binary");
   response.setHeader("Content-Disposition",
       "attachment; filename=\"" + pieceJointe.getLbnompcj() + "\"");// fileName);
   response.getOutputStream().write((byte[]) lrFile.get("CONTENT"));
   response.setContentLength(((byte[]) lrFile.get("CONTENT")).length);
   response.getOutputStream().close();
   response.flushBuffer();
}

but it doesn't work and I don't see any error on my console. Do I need to add an additional configuration to my response object ?

djm.im
  • 3,295
  • 4
  • 30
  • 45
  • 2
    *but it doesn't work and i dont have any error in my console* — What's the error and how is the code supposed to work? Could you please edit your question and add more information? – deHaar Dec 09 '19 at 14:17
  • Hello , this code is used to force the donwload of the file into my browser but nothing happens after the execution of this code – Adnen Sadfi Dec 09 '19 at 14:20
  • To exclude the most common beginner's mistake: are you using ajax to hit the "web service"? – BalusC Dec 09 '19 at 15:51
  • yes i'm using ajax to call my method – Adnen Sadfi Dec 10 '19 at 06:55
  • OK, there's nothing wrong with your servlet. The problem is because you're using ajax instead of a simple `window.location=servletUrl`. Next time unit-test your servlet (without ajax). You should have noticed that your code actually worked just fine. See the abovelinked dupe for some solutions/alternatives. – BalusC Dec 10 '19 at 11:10

3 Answers3

2

you are setting your content Length after writing the output.

  response.getOutputStream().write((byte[]) lrFile.get("CONTENT"));
  response.setContentLength(((byte[]) lrFile.get("CONTENT")).length);

to

 response.setContentLength((long) lrFile.get("CONTENT").length);
 response.getOutputStream().write((byte[]) lrFile.get("CONTENT"));
g kexxt
  • 121
  • 1
  • 5
0

As you do not filename*= in the content disposiition, the file name should not contain special characters.

You still should not have written to the output (neither getOutputSteam() or getOutputWriter()).

   response.setContentType("application/force-download");
   response.setContentLength(content.length);
   //response.setHeader("Content-Transfer-Encoding", "binary");
   String filename = URLEncoder.encode(pieceJointe.getLbnompcj(), "UTF-8");
   response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

   response.getOutputStream().write(content);
   response.getOutputStream().close();

At the moment I cannot test the code for content disposition. So read at the reference. It could be something like:

   response.setHeader("Content-Disposition", "attachment; filename*=UTF-8\'\'" + filename);

reset should not be done, resetBuffer is more a hack should something alredy have been written but still reside in the buffer.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
0

This might be useful for you s3Client getObject as byte[] fileContent.

byte[] fileContent = s3Client.getObject(imagesBucketName, documentsFolderName, metadata.getFileName());
        resource = new InputStreamResource(new ByteArrayInputStream(fileContent));

FileResponse fileResponse = new FileResponse();
    fileResponse.setInputStreamResource(resource);
    fileResponse.setMimeType(metadata.getContentType());
    fileResponse.setFileSize(metadata.getFileSize());

@GetMapping("/logo/{spaceId}")
public ResponseEntity<InputStreamResource> getCompanyLogo(@PathVariable("spaceId") Integer spaceId)
        throws FileDownloadException, InvalidInputException {
    FileResponse fileResponse = companySpaceService.downloadCompanyLogo();
    return ResponseEntity.ok().contentLength(fileResponse.getFileSize())
            .contentType(MediaType.parseMediaType(fileResponse.getMimeType()))
            .body(fileResponse.getInputStreamResource());
}