下载多个文件Java Spring

问题描述:

我试图在spring-mvc应用程序中通过一个http get请求下载多个文件.

I am trying to download multiple file with one http get request in my spring-mvc application.

我看过其他文章,说您可以压缩文件并发送该文件,但是对于我来说,这并不理想,因为不能从应用程序直接访问该文件.要获取文件,我必须查询REST接口,该接口从hbase或hadoop传输文件.

I have looked at other posts, saying you could just zip the file and send this file but it's not ideal in my case, as the file are not in direct access from the application. To get the files I have to query a REST interface, which streams the file from either hbase or hadoop.

我可以拥有大于1 Go的文件,因此将文件下载到存储库中,将其压缩并发送给客户端将太长. (考虑到大文件已经是zip,压缩不会压缩它们.)

I can have files bigger than 1 Go, so downloading the files into a repository, zipping them and sending them to the client would be too long. (Considering that the big file are already zip, zipping won't compress them).

我在此处可以使用multipart-response一次下载多个文件,但没有任何结果.这是我的代码:

I saw here and there that you can use multipart-response to download multiple files at once, but I can't get any result. Here is my code:

String boundaryTxt = "--AMZ90RFX875LKMFasdf09DDFF3";
response.setContentType("multipart/x-mixed-replace;boundary=" + boundaryTxt.substring(2));
ServletOutputStream out = response.getOutputStream();
        
// write the first boundary
out.write(("\r\n"+boundaryTxt+"\r\n").getBytes());

String contentType = "Content-type: application/octet-stream\n";
        
for (String s:files){
    System.out.println(s);
    String[] split = s.trim().split("/");
    db = split[1];
    key = split[2]+"/"+split[3]+"/"+split[4];
    filename = split[4];
            
    out.write((contentType + "\r\n").getBytes());
    out.write(("\r\nContent-Disposition: attachment; filename=" +filename+"\r\n").getBytes());
    
    InputStream is = null;
    if (db.equals("hadoop")){
        is = HadoopUtils.get(key);
    }
    else if (db.equals("hbase")){
        is = HbaseUtils.get(key);
    }
    else{
        System.out.println("Wrong db with name: " + db);
    }
    byte[] buffer = new byte[9000]; // max 8kB for http get
    int data;
    while((data = is.read(buffer)) != -1) { 
        out.write(buffer, 0, data);
    } 
    is.close(); 
       
    // write bndry after data
    out.write(("\r\n"+boundaryTxt+"\r\n").getBytes());
    response.flushBuffer();
    }
// write the ending boundary
out.write((boundaryTxt + "--\r\n").getBytes());
response.flushBuffer();
out.close();
}   

奇怪的是,根据导航器,我得到不同的结果.在Chrome(在控制台中查看)和Firefox中什么都没发生,我收到提示要求下载每个文件的提示,但它的类型和名称都不正确(控制台中也没有).

The weird part is that I get different result depending on the navigator. Nothing happends in Chrome (looked at the console) and in Firefox, I got a prompt asking to download for each file but it doesn't have the right type nor the right name (nothing in console either).

我的代码中是否有任何错误?如果没有,还有其他选择吗?

Is there any bug in my code? If no, is there any alternative?

修改

我也看到了这篇文章:

I also saw this post: Unable to send a multipart/mixed request to spring MVC based REST service

编辑2

该文件的内容正是我想要的,但是为什么我不能获得正确的名称,为什么chrome无法下载任何内容?

The content of this file is what I want, but why can't I get the right name and why can't chrome download anything?

您可以使用multipart/x-mixed-replace内容类型来实现. 您可以像response.setContentType("multipart/x-mixed-replace;boundary=END");这样添加并循环浏览文件,并将每个文件写入响应输出流. 您可以查看此示例供参考.

You can do it using the multipart/x-mixed-replace content type. You can add this like response.setContentType("multipart/x-mixed-replace;boundary=END"); and loop through the files and write each to the response output stream. You can check out this example for reference.

另一种方法是创建一个REST端点,该端点将允许您下载一个文件,然后针对每个文件分别重复调用该端点.

Another approach is to create a REST end point that will let you download one single file and then repeatedly call this end point for each file individually.