Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call servlet from GWT with post data and download file generated by the servlet

I have my ExportServlet, which are generating XLSX files (Excel) which my user will request from my GWT application by clicking a export button.

If I use the GET approach, the user are prompted to download the file. The code looks like this:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
{
    try
    {
        byte[] xlsx = createTest("");
        sendXLSX(resp, xlsx, "test.xlsx");
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
 }

void sendXLSX(HttpServletResponse response, byte[] bytes, String name)
        throws IOException
{
    ServletOutputStream stream = null;

    stream = response.getOutputStream();
    response.setContentType(CONTENT_TYPE_XLSX);
    response.addHeader("Content-Type", CONTENT_TYPE_XLSX);
    response.addHeader("Content-Disposition", "inline; filename=" + name);
    response.setContentLength((int) bytes.length);
    stream.write(bytes);
    stream.close();
}

This is invoked by the GWT client in the following manner:

String url = GWT.getModuleBaseURL() + "ExportServlet";
Window.open(url, "", "");

and the user is prompted to download the file. Good, thats what I want :)

But I would like to attach a lot of data in the request, and afaik, there is a limit to how much data you can put in a URL parameter ("ExportServlet?data=..."), so I would like to wrap that in a POST request instead.

I have tried the following from GWT:

String url = GWT.getModuleBaseURL() + "ExportServlet";
RequestBuilder builder = new RequestBuilder(
                            RequestBuilder.POST, url);
Request response = builder.sendRequest("test data", new RequestCallback() 
{
    @Override
    public void onResponseReceived(Request request, Response response)
    {
        System.out.println("");
    }

    @Override
    public void onError(Request request, Throwable exception)
    {
        System.out.println("");
    }
});

and this in my servlet:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
{
    try
    {
        String data = req.getReader().readLine();
        byte[] xlsx = createTest(data);
        sendXLSX(resp, xlsx, "test.xlsx");
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

but the user is not prompted to download the file. The doPost method is invoked and the data is received by the servlet, but am I supposed to extract the XLSX file from the response which I receive in the GWT app? and how am I suppose to do that?

Appreciate any help or comments :)

like image 836
Rasmus Nielsen Avatar asked Aug 02 '12 12:08

Rasmus Nielsen


1 Answers

Ok, so I went with the 3rd approach in the linked SO question.

Create a FormPanel, put your data in hidden fields, set the URL to your servlet, call the submit method programmatically on the form and the described problem in this SO question will be solved.

Details on how to extract data from the hidden fields:

So my doPost looks similar to this:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) { 
    ServletFileUpload upload = new ServletFileUpload();
    FileItemIterator iterator = upload.getItemIterator(req);

    while (iterator.hasNext()) {
        FileItemStream item = iterator.next();
        if (item.isFormField()) {
            String name = item.getFieldName();
            if (name.equalsIgnoreCase("fieldName")) {
                data = Streams.asString(item.openStream(), ENCODING_UTF8);
            }
        }
    }
    ...

I have a hidden field in my form with the name "fieldName", where the data is put and submitted to the servlet. Hope this helps :)

like image 90
Rasmus Nielsen Avatar answered Nov 19 '22 11:11

Rasmus Nielsen