使用struts2和Ajax下载文件时如何放置进度条

2022-01-16 00:00:00 progress-bar jquery ajax java struts2

我无法放置进度条,因为它直接重定向页面并下载文件.

解决方案

这么多问题(大部分是隐含的)一个问题!

<块引用>

使用struts2和Ajax下载文件时如何放置进度条

  1. 如果不需要,不要使用 AJAX 下载.当您在浏览器中打开文件 (contentDisposition: inline) 时,只需使用新的 Tab(/Window).当您下载文件(contentDisposition: attachment)时,当前页面不会受到影响.您可以在 结果:

    <result name="success" type="stream"><param name="contentType">image/jpeg</param><param name="contentDisposition">附件;filename="document.pdf"</param><param name="contentLength">${lengthOfMyFile}</param></结果>

    private long lengthOfMyFile;//使用 Getter公共字符串执行(){/* 文件加载和其他东西 ... */lengthOfMyFile = myFile.length();返回成功;}

<块引用>

假设文件太重.所以这需要时间,所以我想防止用户不点击其他按钮

  1. 如果您想节省带宽,那么您需要进行 Web 服务器 配置.这篇文章可能会有所帮助:

    • 限制数量每个客户端的下载量

    如果您不关心防止泛滥的请求,而只是防止客户端的多个并发下载,您可以使用会话变量,放在开头并在结尾删除方法,在下载操作开始时检查它是否存在.如果它存在,您将不会下载,否则,您将:

    //Action 必须实现 SessionAware 接口私有地图<字符串,对象>会议;//使用 Setterprivate final static String BUSY = "我很忙.再试一次";公共字符串执行(){if (session.get(BUSY)!=null){LOG.debug("另一个下载正在进行中.我停在这里");返回无;}尝试 {session.put(忙,忙);/* 文件加载和其他东西 ... */} 最后 {session.remove(忙);返回成功;}}

    良好的旧信号量.

I am not able to put progress bar because it is directly redirecting the page and file is downloaded.

解决方案

So many questions (most of them implicit) in a single one!

How to put progress bar when downloading file using struts2 and Ajax

  1. Do not use AJAX downloading if it is not needed. When you open a file in the browser (contentDisposition: inline), simply use a new Tab(/Window). When you download a file (contentDisposition: attachment), the current page won't be affected. You can find several ways to do this in this answer, for example:

    <s:url action="downloadAction.action" var="url">
        <s:param name="param1">value1</s:param>
    </s:url>
    <s:a href="%{url}" >download</s:a>
    

how can we put browser progress bar?

  1. Every browser has an inbuilt progress bar that is shown when downloading files:

    The browser is not able to draw the progress bar only in the case the length of the file to be downloaded has not been provided. To instruct the browser, you can use the contentLength header, that is also directly available in the Stream result:

    <result name="success" type="stream">    
        <param name="contentType">image/jpeg</param>
        <param name="contentDisposition">attachment;filename="document.pdf"</param>
        <param name="contentLength">${lengthOfMyFile}</param>
    </result>
    

    private long lengthOfMyFile; // with Getter
    
    public String execute(){
        /* file loading and stuff ... */
        lengthOfMyFile = myFile.length();
        return SUCCESS;
    }
    

Suppose if file is too heavy. So it take time so I want to prevent user not click to other button

  1. If you want to save bandwidth, then you need to work on your Web Server configuration. This article might help:

    • Limit the number of downloads per client

    If instead you don't care about preventing flooding requests, but only preventing multiple concurrent downloads for a client, you can use a session variable, put at the beginning and removed at the end of your method, checking for its existence at the beginning of your download action. If it exist, you won't download, otherwise, you will:

    // The Action must implement the SessionAware interface
    
    private Map<String,Object> session; // with Setter
    private final static String BUSY = "I'm busy. Try again";
    
    public String execute(){
        if (session.get(BUSY)!=null){
           LOG.debug("Another download is in progress. I stop here");
           return NONE;
        }
        try {
            session.put(BUSY,BUSY);
            /* file loading and stuff ... */
        } finally {
            session.remove(BUSY);
            return SUCCESS;
        }
    }
    

    The good old semaphore.

相关文章