0

In my webapp I want the user to download a csv file as a response to a POST ajax request. The response is properly sent, and looks ok, but at ajax.success() nothing happens.

I don't want to permanently write a file on the server, so I'm directly writing in a PrintWriter, I've read this should work.

Here is the code for the servlet:

public void doPost(HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException {
    BufferedReader reader = request.getReader();
    myData data = mapper.readValue(reader, myData.class);
    List<City> cities = data.getCities();
    String filename = domain+".csv";
    response.setContentType("application/csv");
    response.setHeader("content-disposition","filename="+filename);
    PrintWriter out = response.getWriter();

    /*writes csv rows to out stream*/
    for (int i = 0; i <= 50; i++) {
        String nome = cities.get(i).getName();
        List<FBHit> results = allQueries.get(nome).get();
        for (FBHit hit : results) {
            hit.writeToCSV(out, nome);
        }
    }
    out.close();
}

here's the code for the asynchronous request:

$.ajax({
                                url: "/socialpa-2/batchQueryServlet",
                                contentType: 'application/json',
                                data: json,
                                Accept: "text/csv",
                                success: function(data, textStatus, jqXHR) {
                                    alert(data);
                                },
                                type: "POST"
                            });

When the request returns, the file content is shown in the alert, but no download is fired. If I remove the alert nothing happens as well. I suspect that the bug is either a wrong value for accept or the use of printwriter.

This is a sample of the CSV file, it looks ok to me

"Alassio","http://facebook.com/-1089066187","Città di Alassio",2644
"Albenga","http://facebook.com/-915266586","Comune di Albenga",100
"Albisola Superiore","http://facebook.com/2031157506","Città di Albisola Superiore",536
"Albissola Marina","http://facebook.com/80387060","Comune di Albissola Marina",597
"Bardineto","http://facebook.com/-317945148","Comune di Bardineto",360
"Bergeggi","http://facebook.com/92600835","Comune di Bergeggi",1214
"Cairo Montenotte","http://facebook.com/1413890265","Città di Cairo Montenotte",206

I should stick to java (since I'm not the owner of the server) and I'd rather not write a file on the server, if possible.

Dev-otchka
  • 327
  • 1
  • 4
  • 20

1 Answers1

1

Java-script cannot save files to a user's computer, for security reasons, and thus can't write bytes it receives from an AJAX request to the file system. However, you can use JavaScript to make the browser initiate the file download with

window.location = "<your path goes here>"

but this will perform a GET request.

You could also generate a form with a POST method and a submit button through javascript and then programatically submit the form, but that might over the top.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • I'm sending a whole json object taken from another service, it's necessary in order to compute the file so I really need to use the post (the json object is quite lenghty and I don't think I want to pass it as a parameter in GET). But probably I can do the window.location thing once the request is successful. I'll try. Could I handle it with a jsp page instead of relying on javascript alone? – Dev-otchka May 22 '13 at 18:08
  • 1
    You could do it by submitting a `
    ` with a POST `method`, possibly with hidden `` elements for the parameters you need to pass.
    – Sotirios Delimanolis May 22 '13 at 18:09