【问题标题】:Downloading file during p:ajax rowSelect event in p:dataTable在 p:dataTable 中的 p:ajax rowSelect 事件期间下载文件
【发布时间】:2020-04-26 13:28:23
【问题描述】:

我想按行点击 primefaces 数据表下载文档文件。我尝试使用这样的 ajax 从 Bean 调用操作:

<p:dataTable
            id="docId"
            value="#{testBean.document}"
            var="doc"
            selectionMode="single"
            selection="#{testBean.selectedDoc}"
            >

            <p:ajax event="rowSelect" listener="#{testBean.actionDownload}"/>

            <p:column>
                ...
            </p:column>
                ...
</p:dataTable>

但是下面的代码并没有执行我想要的。我的行动逻辑是正确的。但似乎下载文件不适用于 ajax 请求。没有反应,下载不执行。

public String actionDownload() {
    try {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();

        StringBuffer contentDisposition = new StringBuffer();
        contentDisposition.append("attachment;");
        contentDisposition.append("filename=\"");
        contentDisposition.append(name);
        contentDisposition.append("\"");

        response.reset();
        response.setContentType("application/x-download");

        response.setHeader("Content-Disposition", contentDisposition.toString());
        ServletOutputStream out = response.getOutputStream();
        response.setContentType("application/x-download");
        out.write(output);
        out.close();
    } catch (IOException e) {
        System.out.println(e.getMessage());
    }
    FacesContext.getCurrentInstance().responseComplete();
    return null;
}

是否可以通过单击数据表行来下载文件?

【问题讨论】:

  • 方法actionDownload()被调用了吗?
  • @Selaron:据我所知不是。值得注意的是,OP 认为它与下载有关,而不是试图在其中放一个 system.out.println
  • @Selaron:是的,方法 actionDownload() 被调用并执行。但是什么也没发生。我通过从 commandButton 调用测试了 actionDownload() 方法,一切正常。但是通过 Ajax 调用并不会带来相同的结果。
  • 看到你缩小了问题的范围。我认为会有重复(因此我还没有回答并希望你缩小问题范围)如果@BalusC 回答没有必要尝试找到重复,因为有 99,999% 的确定性不是

标签: jsf primefaces datatable download


【解决方案1】:

您无法使用 JSF/PrimeFaces Ajax 下载文件。改为非 Ajax 请求。

将&lt;p:ajax&gt; 中的ajax 监听器替换为oncomplete 中的GET 请求,例如:

<p:ajax event="rowSelect" oncomplete="window.location='#{request.contextPath}/download/#{doc.id}'"/>

并用普通的 Servlet 替换支持 bean 方法 actionDownload(),例如:

@WebServlet("/download/*")
public class Download extends HttpServlet {

    @Inject
    private DocumentService service;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Document document = service.find(Long.valueOf(request.getPathInfo().substring(1)));
        response.setContentType(getServletContext().getMimeType(document.getFileName()));
        response.setContentLength(document.getContent().length);
        response.setHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(document.getFileName(), "UTF-8") + "\"");
        response.getOutputStream().write(document.getContent());
    }

}

【讨论】:

    猜你喜欢
    • 2016-08-06
    • 2018-12-19
    • 2014-12-26
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 2013-01-15
    相关资源
    最近更新 更多