如何使用struts2的和Ajax下载文件时把进度条如何使用、进度条、文件、Ajax

2023-09-11 00:35:57 作者:命里不缺狗°

我不能够把进度条,因为它是直接重定向页面,文件被下载。

访问Point.js

 如果(strExport ==CSV)
    {
    VAR SLIST = JSON.stringify(searchList);
    varlink = window.location.href;
    window.location.href =$ {}基地/ APP / AJAX / CSVUtility SLIST =?+ SLIST;
    $阿贾克斯({
        网址:链接,
        成功:功能(数据){
        },
        错误:函数(XHR,ajaxOptions,thrownError){
             警报(错误+ thrownError);
            alertAndLoadDefaultViewIfLockUnavailable(XHR);
        }
    });
    }
 

在struts.xml

 <作用NAME =CSVUtility级=com.assaabloy.stg.dsr.support.action.ActivityAction方法=CSVUtility>
         <结果名称=成功TYPE =流>
          < PARAM NAME =的contentType>应用程序/八位字节流< /参数>
          < PARAM NAME =inputName>的InputStream< /参数>
          < PARAM NAME =contentDisposition>附件;文件名=$ {文件名}< /参数>
          < PARAM NAME =BUFFERSIZE> 1024< /参数>
        < /结果>
    < /作用>
 

活动操作

 私人的InputStream exportAsCSV()抛出IOException异常{

    ByteArrayOutputStream缓冲区=新ByteArrayOutputStream();
    PrintWriter的PrintWriter的=的新PrintWriter(缓冲区);

    CSVWriter作家=新CSVWriter(PrintWriter的);
     的String [] strarray =新的String [ReportHeaderMapper.getAccessPointColumnList()的大小()];

     writer.writeNext(ReportHeaderMapper.getAccessPointColumnList()的toArray(strarray));
/ *的String []头=(字符串[])ReportHeaderMapper.getAccessPointColumnList()的toArray()。
    writer.writeNext(头);
* /
activityList = activityDT​​OList.getActivityDT​​Os();
    ReportHeaderMapper.setData(activityList);

    对于(名单<字符串> rowList:ReportHeaderMapper.getAccessPointAllRows()){
        的String [] csvData =新的String [rowList.size()];
        writer.writeNext(rowList.toArray(csvData));

    }
    writer.close();
    LOGGER.info(CSV文件创建成功。);
    LOGGER.info(CSV activityList大小+ activityList.size());
    返回新ByteArrayInputStream的(buffer.toByteArray());
}
 
Struts2的Ajax开发

解决方案

这么多的问题(其中大部分隐含的)在一个单一的一个!

  

如何利用Struts2的和Ajax下载文件时把进度条

不要使用AJAX下载,如果它是不需要的。当您在浏览器中打开一个文件( contentDisposition:内联),只需使用一个新的选项卡(/窗口)。当您下载一个文件( contentDisposition:附件),当前页面将不会受到影响。你可以找到几种方法可以做到这一点这个答案的,例如:

< S:URL操作=downloadAction.actionVAR =URL>     < S:参数名称=参数1>值1< / S:参数> < / S:网址> < S:A HREF =%{URL}>下载< / S:A>

  

我们怎样才能把浏览器的进度条?

每一个浏览器在下载文件时显示一个内置的进度条:

的浏览器是不能够只绘制的情况下要下载的文件的长度没有被提供的进度条。要指示浏览器,你可以使用 CONTENTLENGTH 头,这也是在的流结果:

<结果名称=成功TYPE =流>     < PARAM NAME =的contentType>为image / jpeg< /参数>     < PARAM NAME =contentDisposition>附件;文件名=document.pdf< /参数>     < PARAM NAME =CONTENTLENGTH> $ {lengthOfMyFile}< /参数> < /结果>

专用长lengthOfMyFile; //吸气剂 公共字符串的execute(){     / *文件载入和东西... * /     lengthOfMyFile = myFile.length();     返回成功; }

  

假设,如果文件是太重了。因此,它需要时间,所以我想prevent用户不点击另一个按钮

如果你想为节省带宽,然后你需要的工作您的 Web服务器的配置上。这篇文章可以帮助:

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

相反,如果你不关心preventing洪水的要求,但只有 preventing多个并发下载一个客户端,您可以使用一个会话变量,把开头和在你的方法的末尾去除,检查它的存在,在你的下载动作的开始。如果它存在,你就不会下载,否则,你会:

  //必须实现SessionAware接口行动

私人地图<字符串,对象>会议; //与二传手
私人最终静态字符串BUSY =我很忙,请再试一次。

公共字符串的execute(){
    如果(session.get(忙)!= NULL){
       LOG.debug(另一个下载过程中我停在这里。);
       返回NONE;
    }
    尝试 {
        session.put(在忙,忙着);
        / *文件载入和东西... * /
    } 最后 {
        session.remove(忙);
        返回成功;
    }
}
 

好老信号灯。

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

Access Point.js

    if(strExport=="CSV")
    {
    var slist = JSON.stringify(searchList);
    varlink=window.location.href;
    window.location.href="${base}/app/ajax/CSVUtility?slist=" + slist ;
    $.ajax({
        url : link,
        success : function(data) {
        },
        error : function(xhr, ajaxOptions, thrownError) {
             alert("error"+thrownError);
            alertAndLoadDefaultViewIfLockUnavailable(xhr);
        }
    }); 
    }

Struts.xml

<action name="CSVUtility" class="com.assaabloy.stg.dsr.support.action.ActivityAction" method="CSVUtility">
         <result name="success" type="stream">
          <param name="contentType">application/octet-stream</param>
          <param name="inputName">inputStream</param>
          <param name="contentDisposition">attachment;filename="${filename}"</param>
          <param name="bufferSize">1024</param>
        </result>
    </action>

Activity Action

private InputStream exportAsCSV() throws IOException {

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    PrintWriter printWriter= new PrintWriter(buffer);

    CSVWriter writer = new CSVWriter(printWriter);
     String[] strarray = new String[ ReportHeaderMapper.getAccessPointColumnList().size()];

     writer.writeNext(ReportHeaderMapper.getAccessPointColumnList().toArray(strarray ));
/*  String[] header = (String[]) ReportHeaderMapper.getAccessPointColumnList().toArray();
    writer.writeNext(header);
*/      
activityList     = activityDTOList.getActivityDTOs();
    ReportHeaderMapper.setData(activityList);

    for(List<String> rowList:ReportHeaderMapper.getAccessPointAllRows()) {
        String [] csvData=new String[rowList.size()];
        writer.writeNext(rowList.toArray(csvData));

    }
    writer.close();
    LOGGER.info("CSV file created successfully."); 
    LOGGER.info("CSV activityList size" + activityList.size());
    return new ByteArrayInputStream(buffer.toByteArray());
}

解决方案

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

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

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?

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

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.