使用post数据从GWT调用servlet并下载servlet生成的文件

9
我有一个名为ExportServlet的程序,能够生成XLSX(Excel)文件。当用户点击导出按钮时,我的GWT应用程序将请求此文件。

如果使用GET方法,用户将会收到下载提示。代码如下:
@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();
}

这是由GWT客户端以以下方式调用的:
String url = GWT.getModuleBaseURL() + "ExportServlet";
Window.open(url, "", "");

用户会收到下载文件的提示。很好,这正是我想要的 :)

但是我希望在请求中附加大量数据,据我所知,URL参数中可以放置的数据有限(“ExportServlet?data=…”),因此我希望将其包装在POST请求中。

我已经尝试了以下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("");
    }
});

这是我的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();
    }
}

但是用户没有收到下载文件的提示。doPost方法被调用并且数据被servlet接收,但我应该从在GWT应用程序中接收的响应中提取XLSX文件吗?我该怎么做呢?
非常感谢任何帮助或评论 :)

2
我发现了这篇帖子:https://dev59.com/W2w05IYBdhLWcg3wXQsg 可能会回答我的问题。我会尝试一下并告诉大家 :)(不知道如何将链接与此SO问题相关联) - Rasmus Nielsen
2个回答

8

好的,我选择了链接的SO问题中的第三个方法。

创建一个FormPanel,在隐藏字段中放置数据,将URL设置为您的servlet,在表单上以编程方式调用submit方法,这样就可以解决此SO问题中描述的问题。

从隐藏字段中提取数据的详细信息:

所以我的doPost看起来类似于这样:

@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);
            }
        }
    }
    ...

我的表单中有一个名为“fieldName”的隐藏字段,数据将被放置并提交到servlet。希望这可以帮助您 :)


1
如果您方便的话,请分享细节。 - Michael Myers
在我的答案中添加了更多细节 - Rasmus Nielsen

0

你好,我有完全相同的问题,通过直接调用servlet并使用以下代码解决了它:

Window.Location.replace(URL.encode(servletUrl));

同时,可以查看此链接相关问题


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接