后台 要做的就是将响应流放入压缩流中,然后压缩流文件目录对象放入压缩流中,当压缩流对象是文件时还需将压缩流放入输出缓冲流中,将文件流读到缓冲流中,然后压缩流关闭压缩流文件目录对象,之后从输出到输入、从外到里依次关闭流。
@GetMapping("/downloadFile")
public void downloadFile(HttpServletResponse response){
response.setCharacterEncoding("utf-8");
ZipOutputStream zos = null;
OutputStream os = null;
OutputStream out = null;
InputStream in = null;
String filename1="aa/bb/cc/";
String filename2="aa/bb/dd/";
String filename3="aa/bb/dd/test.txt";
FileInputStream fis =null;
try {
fis = new FileInputStream("./files/ftp学习.txt");//输入流
os = response.getOutputStream();//响应流
zos = new ZipOutputStream(os);//压缩流
ZipEntry zipEntry = new ZipEntry(filename1);//压缩流目录对象
zos.putNextEntry(zipEntry);//将压缩流目录对象放入压缩流中
zos.closeEntry();//直接关闭压缩流目录对象
ZipEntry zipEntry2 = new ZipEntry(filename2);
zos.putNextEntry(zipEntry2);
zos.closeEntry();
ZipEntry zipEntry3 = new ZipEntry(filename3);
zos.putNextEntry(zipEntry3);
//缓冲流处理文件流
in = new BufferedInputStream(fis);
out = new BufferedOutputStream(zos);
byte[] buff = new byte[1024];
int read;
while ((read = in.read(buff)) != -1) {
System.out.println(buff);
out.write(buff, 0, read);
out.flush();
}
zos.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}finally{
//从输出到输入关闭流,从外到里关闭流。
try {
if(out!=null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(os!=null){
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(zos!=null){
zos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(in!=null){
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fis!=null){
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
前台 用原生的ajax异步请求 发送请求,处理后台传过来的响应流,然后浏览器下载成相应文件。
downloadFileMethod:function() {
alert(tokenVal);
var downloadUrl=this.downloadUrl; //下载地址;
var fileName="test.zip"; //下载的文件;
// var postParam; //参数;
var methodType="batchDownload"; //请求类型;单个,还是批量
var that = this;
var xhr = new XMLHttpRequest();
xhr.open('GET', downloadUrl, true);
xhr.setRequestHeader("Authorization", "Bearer " + tokenVal);
//可以将`xhr.responseType`设置为`"blob"`也可以设置为`" arrayBuffer"`
xhr.responseType = 'blob';
xhr.onload = function(e) {
if(this.readyState == 4 && this.status == 200) {
const blob = this.response;
if('download' in document.createElement('a')) { // 非IE下载
const elink = document.createElement('a')
elink.download = fileName;
elink.style.display = 'none';
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href) // 释放URL 对象
document.body.removeChild(elink)
that.batchDownloadDis=false;
} else { // IE10+下载
navigator.msSaveBlob(blob, fileName)
that.batchDownloadDis=false;
}
} else if(this.status == 404) { //磁盘文件被删除,返回404
that.batchDownloadDis=false;
var notfilenames = decodeURIComponent(xhr.getResponseHeader('notfilenames')); //未找到的文件名称
if(notfilenames != null) {
if(methodType == "batchDownload") {
that.$message({
showClose: true,
message: notfilenames + ' 文件未找到!请重新勾选!',
type: 'error'
});
}
if(methodType == "singleDownload") {
that.$message({
showClose: true,
message: '文件未找到!',
type: 'error'
});
}
}
} else {
that.batchDownloadDis=false;
that.$message({
showClose: true,
message: '下载失败!',
type: 'error'
});
}
};
xhr.send();
}