【问题标题】:How to download file from httpServlet with Jquery?如何使用 Jquery 从 httpServlet 下载文件?
【发布时间】:2013-07-25 12:28:19
【问题描述】:

在我的应用程序中,在客户端创建了一个 json 对象。这个对象被发布到一个 HttpServlet,它根据 POST 数据创建一个 pdf 文件。

文件被发送回给用户。调用 succes 函数,并记录流数据。但是,我希望下载该文件。

如何做到这一点?

我的客户端代码:

$(document).ready(function() {
// when the print button is clicked
$('#exportButton').click(function() {

    var tableIdx = performanceDetailTableController.getTableIdx();

    var allData = {
        "shipTable1":{
            "rows":[
                {  "latitude":"12323","longitude":"213213"},
                {  "latitude":"213213","longitude":"543543"}
            ]},
        "shipTable2":{
            "rows":[
                {  "latitude":"12323", "longitude":"213213"},
                {  "latitude":"213213","longitude":"543543"}
            ]}
        }

    var postData = JSON.stringify(allData);

    $.ajax({
        type : "POST",
        url : 'pdfServlet',
        contentType: "application/json; charset=utf-8",
        data : postData,
                    async : false,
        success : function(data) {
            alert("got some data");
            console.log(data);
        },
    });
});

});

以及创建文件的 servlet:

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

    // get the json content
    StringBuffer jsonContent = getPostedContent(request);

    log.info(jsonContent.toString());

    // convert json to pojo's
    Tables tables = getTablesFromString(jsonContent);

    // create a xml stream
    ByteArrayOutputStream xml = new XmlConverter().getXMLSource(tables);

    // put the xml on the request
    request = setXmlOnRequest(request, xml);

    // create pdf data of the pdf-able xml content
    ByteArrayOutputStream pdf = new PdfHandler().createPdfDataStream(request);

    // response = createResponseheaders(response, request);
    response.setContentType("application/pdf");
    response.setContentLength(pdf.size());
    response.setHeader("Content-disposition", "attachment; filename=test.pdf");
    response.setCharacterEncoding("utf-8");
    response.getOutputStream().write(pdf.toByteArray());

    //close the streams
    pdf.close();
    response.getOutputStream().close();
}

日志中的输出:

%PDF-1.4
%
4 0 obj
<<
/Producer (Apache FOP Version SVN branches/fop-0_95)
/CreationDate (D:20130725162007+02'00')
>>
endobj
5 0 obj
<<
  /N 3
  /Length 11 0 R
  /Filter /FlateDecode
>>
stream
xwTSϽ7PhRHH.*1  J 

*我的解决方案:*

请参阅http://www.particletree.com/notebook/ajax-file-download-or-not/ 获取指针

我创建了一个带有一个隐藏字段的表单:

        <button id="exportButton">export</button>
    <form id="exportForm" method="post" action="pdfServlet">
        <input type="hidden" value="empty" id="pdf_data" name="pdf_data" />
    </form>

比我将我的 jquery 后数据控制器更改为:

    $('#exportButton').click(function() {

    var tableIdx = performanceDetailTableController.getTableIdx();

        var allData = {
        "shipTable1":{
            "rows":[
                {  "latitude":"12323","longitude":"213213"},
                {  "latitude":"213213","longitude":"543543"}
            ]},
        "shipTable2":{
            "rows":[
                {  "latitude":"12323", "longitude":"213213"},
                {  "latitude":"213213","longitude":"543543"}
            ]}
        } 



    var postData = JSON.stringify(allData);

    // put the data on the hidden form field in the export form
    $('#pdf_data').val(postData);

    // and submit the form
    $('#exportForm').submit();

});

所以现在当我单击导出按钮时,表单中的隐藏字段会获取要发布的数据,并且数据会以 www-form 编码的形式发布。

这样 servlet 可以处理请求并将文件下载到客户端。

【问题讨论】:

  • 您不能使用 ajax 强制下载文件。
  • Ajax 响应不允许下载文件。

标签: java jquery servlets post


【解决方案1】:

您不能使用 ajax 下载文件。出于明显的安全原因,JavaScript 没有任何设施来触发 Save As 对话与 JavaScript 上下文中任意检索/生成的内容。如果可能的话,万维网看起来会大不相同。

如果您坚持使用 JS/jQuery,则需要发送同步 GET 请求。您可以使用window.location 来做到这一点(您只需将doPost() 重命名为doGet())。

window.location = 'pdfServlet?param1=value1&param2=value2';

或者,扔掉所有不必要的 JS/jQuery,只使用纯 HTML &lt;form action="pdfServlet" method="post"&gt;&lt;input type="submit"&gt;。额外的好处是它可以在禁用 JS 的浏览器中工作。

如果您获取 ajax 的唯一原因实际上是天真地尝试避免刷新页面,那么我可以告诉您,如果响应具有 Content-Disposition: attachment 标头,这真的不会发生。所以那部分已经是安全的了。

【讨论】:

  • 他的请求是一个 POST。将不得不玩弄那个。
  • 所以基本上我会让用户发布其内容,用它创建一个 pdf 文件,将其写入服务器上的磁盘并为用户提供一个链接,他可以从中下载文件?跨度>
  • @SotiriosDelimanolis 我不认为在这种情况下使用表格是可能的,但会检查出来。
  • jorrebor,只需编写 PDF 即可回复。就像你现在一样。您的 servlet 完全没问题。你唯一的问题是你如何调用它。它应该同步完成,而不是异步完成。
  • 我想纠正我之前评论中的“你的 servlet 完全没问题”的说法。实际上不是。如果您的输入已经完全在内存中,就像byte[] 一样,那么整个读/写循环是完全没有必要的。只需执行response.getOutputStream().write(pdf.toByteArray());。请注意,如果PdfHandler 立即写信给response.getOutputStream(),而不是在内存中创建byte[],效率会更高。但这一切都与发送文件下载的实际功能无关。
猜你喜欢
  • 1970-01-01
  • 2018-11-02
  • 2010-11-20
  • 2023-03-21
  • 2012-10-03
  • 2013-02-26
  • 2021-12-18
  • 2012-06-25
相关资源
最近更新 更多