vlio20
vlio20

Reputation: 9295

Download file Safari

I am trying to trigger file download, and I am having issues to do this on Safari (FireFox & Chrome works as expected).
Here is my Java code:

  @RequestMapping(method = RequestMethod.GET, produces = "text/csv")
  @ResponseBody
  public String getReports(
      final HttpServletResponse response,
      final @RequestParam String data) throws ParseException {
    response.setHeader("Content-type", "text/csv; charset=utf-8");
    response.setHeader("Content-Disposition","attachment; filename='view.csv'");
    String csv = exportCurrentService.extractMatrix(data);
    response.setContentLength(csv.length());

    return csv;
  }

And here is my client code:

  downloadURI(url, name) {
    const a = document.createElement('a');
    a.href = url;
    a.download = name;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  }

In Safari the response is printed out on the screen (loaded on the same page).

Note: that I have tried other methods suggested on SO but each has it's own problems.

Update: In the response header I see that the Content-Disposition is set to inline instead of attachment. Why this is happening?

What did I do wrong?

Upvotes: 8

Views: 2575

Answers (3)

vlio20
vlio20

Reputation: 9295

My service is placed behind a routing module (which is the proxy for all the micro services). The issue was in this module (the proxy) it was overwriting the headers and cookies of the micro app service.

Setting the code as described in the question did the trick.

Upvotes: 0

H. Khan
H. Khan

Reputation: 123

This won't compile, it just represents what you should do.

response.setContentType("application/force-download");
response.setContentLength((int)f.length());
        //response.setContentLength(-1);
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-Disposition","attachment; filename=\"" + "xxx\"");//fileName);
...
...
File f= new File(fileName);

InputStream in = new FileInputStream(f);
BufferedInputStream bin = new BufferedInputStream(in);
DataInputStream din = new DataInputStream(bin);

while(din.available() > 0){
    out.print(din.readLine());
    out.print("\n");
    //this is from another answer I saw awhile ago while trying to do the same thing
}

This is from another post that I saw when trying to do the same thing. The original author was Vineet Reynolds. I am new to SO so please inform me if this is bad practice.

Upvotes: 1

NikNik
NikNik

Reputation: 2301

Try without @ResponseBody and with produces = MediaType.APPLICATION_JSON_UTF8_VALUE

Upvotes: 1

Related Questions