-2

How to download all files in the file directory when clicking the export or download at the same time?

At present, all the files in the file directory have been obtained, then all the files are placed in the list, and then the stream is written after traversing all the files. However, when importing the second file, it will report cannot reset buffer after response has been committed

The source of the problem is in this code: // response.reset();

Code:

   String filePath = "/code/data/";
    // Get all file addresses of the directory
    List<String> filePathList = getFilePath(filePath);

    //Create thread pool

    for (String str : filePathList){

     download(request, response, str);

   }

    private void download(HttpServletRequest request,  
                HttpServletResponse response,String filePath) {
    File file = new File(filePath);

    //Gets the file name.

    String fileName = file.getName();

    InputStream fis = null;

   try {

    fis = new FileInputStream(file);

    request.setCharacterEncoding("UTF-8");

    String agent = request.getHeader("User-Agent").toUpperCase();

    if ((agent.indexOf("MSIE") > 0) || ((agent.indexOf("RV") != - 1) &&  
                                     (agent.indexOf("FIREFOX") == -1))) {

    fileName = URLEncoder.encode(fileName, "UTF-8");

    } else {

    fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");

    }

    // response.reset();

    response.setCharacterEncoding("UTF-8");

    response.setContentType("application/force-download");
    // Set forced download not to open

    response.addHeader("Content-Disposition",  
                       "attachment; filename=" + fileName);

    response.setHeader("Content-Length", String.valueOf(file.length()));

    byte[] b = new byte[1024];

    int len;

    while ((len = fis.read(b)) != - 1) {

      response.getOutputStream().write(b, 0, len);

    }

    response.flushBuffer();

    fis.close();

    } catch (IOException e) {

    throw new RuntimeException(e);

    }
 }
}

What are the good solutions Thanks

tom_mai78101
  • 2,383
  • 2
  • 32
  • 59
xiaoximi
  • 1
  • 1
  • 2
    Please format your code properly. Correct the indentation, and wrap long lines so that there isn't a horizontal scroll bar. (People will be more inclined to help you if your code is readable.) – Stephen C Sep 05 '21 at 02:33
  • Also please add the full error message and exception stack trace to your question. – tgdavies Sep 05 '21 at 02:55

1 Answers1

1

I have not read your code in detail because the bad formatting makes my head hurt.

However, from a superficial reading, it looks like this server-side code is trying to deliver multiple files in response to a single HTTP request.

AFAIK, that is not possible. The HTTP request / response model does not support this. It certainly does not allow a servlet to:

  • change response headers after the response output stream has been opened
  • do anything after the response output stream has been closed.

(Your code appears to be trying to do both of those things!)

So, you have to do it differently. Here are some possibilities:

  1. On the server side, assemble all of the files to be downloaded into (say) a temporary ZIP file and then send that. Leave it to the user to unpack the ZIP file ... or not ... as they want.

    This is often the best approach. Imagine how annoyed you would be if a few thousand separate files unexpectedly landed in your web browser's Downloads folder.

  2. As 1. and also do something on the client side to transparently unpack the files from the ZIP and put them in the right place in the client's file system.

    The "something" could be custom javascript embedded in the web page, or a custom client implemented in Java ... or any other language. (But in the former case, there may be a security issue in allowing sandboxed javascript to write files in arbitrary places without the user confirming each file ... tedious.)

  3. You might be able to send a "multipart" document as the response. However from what I have read, most browsers don't support multipart for downloads; e.g. some browsers will discard all but the last part. (Note: multipart is not designed for this purpose ...)

  4. Change things so that an HTTP request only downloads one file at a time from the directory, and add some client-side stuff to 1) fetch a list of files from the server and iterate the list, fetching each file.

See also: Download multiple files with a single action

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216